【问题标题】:ifelse makes factor 'forget' its levels orderifelse 使因素“忘记”其水平顺序
【发布时间】:2020-09-16 09:08:36
【问题描述】:

我有一个包含两个因素的数据框,比如这个:

data <- data.frame(
  x = factor(rep(letters[1:3], 2)),
  y = factor(rep(c('z','x','y'), each=2), c('z','x','y'))
)

 data
  x y
1 a z
2 b z
3 c x
4 a x
5 b y
6 c y

我想将所有xays 转换为NAs。所以我尝试:

factor(ifelse(data$x=='a', NA, as.character(data$y)))
<NA> z    x    <NA> y    y   
Levels: x y z

获得与原始数据不同的级别顺序,即:

data$y
z z x x y y
Levels: z x y

除了像这样的蛮力之外,您能否提出任何保持原始顺序的方法:

factor(ifelse(data$x=='a', NA, as.character(data$y)), c('z','x','y'))
<NA> z    x    <NA> y    y   
Levels: z x y

【问题讨论】:

  • data[data$x == "a", "y"] &lt;- NA(就我个人而言,我几乎从不在我的代码中使用ifelse。)
  • 谢谢!为什么不把它变成一个答案?
  • 太琐碎了。
  • 有用 + 简短 > 琐碎

标签: r factors


【解决方案1】:

你的方法看起来不错。如果不想手动设置新的关卡,可以参考data$y的关卡。

factor(ifelse(data$x == 'a', NA, as.character(data$y)), levels(data$y))

# [1] <NA> z    x    <NA> y    y   
# Levels: z x y

您也可以使用replace(),它不会重置关卡。

replace(data$y, data$x == 'a', NA)

# [1] <NA> z    x    <NA> y    y   
# Levels: z x y

【讨论】:

  • 我喜欢replace 解决方案。谢谢!
【解决方案2】:

您也可以使用[] 来保留因子属性:

data$y[] <- ifelse(data$x=='a', NA, as.character(data$y)) 
str(data$y)
# Factor w/ 3 levels "z","x","y": NA 1 2 NA 3 3

【讨论】:

    【解决方案3】:

    根据 Roland 的评论,这是一个很好的解决方案,我提供了 tidyverse 解决方案:

    library(tidyverse)
    library(magrittr)
    
    data %>% 
      mutate(y = y %>% inset(x=='a', value=NA)) %>% 
      pull(y)
    
    <NA> z    x    <NA> y    y   
    Levels: z x y 
    

    也许它对某人有用:)

    另一个选择,感谢 Darren Tsai:

    data %>% 
      mutate(y = y %>% replace(x=='a', NA)) %>% 
      pull(y)
    
    <NA> z    x    <NA> y    y   
    Levels: z x y 
    

    【讨论】:

      猜你喜欢
      • 2018-12-07
      • 1970-01-01
      • 2017-07-14
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 2020-09-29
      • 2021-11-17
      相关资源
      最近更新 更多