ifelse使因子“忘记”其水平顺序

问题描述

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

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

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

我想将yx的所有a变成NA s。所以我尝试:

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',as.character(data$y)),'y'))
<NA> z    x    <NA> y    y   
Levels: z x y

解决方法

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

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
,

您的方法看起来不错。如果您不想手动设置新级别,则可以将data$y级别作为参考。

factor(ifelse(data$x == 'a',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
,

基于罗兰(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 

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...