我试图将变量的值更改为NA值,如果它们不在向量中:
sample <- factor(c('01', '014', '1', '14', '24'))
df <- data.frame(var1 = 1:6, var2 = factor(c('01', '24', 'none', '1', 'unknown', '24')))
df$var2 <- ifelse(df$var2 %in% sample, df$var2, NA)
Run Code Online (Sandbox Code Playgroud)
由于某种原因,R不保留因子变量的原始值,而是将它们转换为数字序列:
> sample <- factor(c('01', '014', '1', '14', '24'))
> df <- data.frame(var1 = 1:6,
var2 = factor(c('01', '24', 'none', '1', 'unknown', '24')))
> class(df$var2)
[1] "factor"
> df
var1 var2
1 1 01
2 2 24
3 3 none
4 4 1
5 5 unknown
6 6 24
> df$var2 <- ifelse(df$var2 %in% sample, df$var2, NA)
> class(df$var2)
[1] "integer"
> df
var1 var2
1 1 1
2 2 3
3 3 NA
4 4 2
5 5 NA
6 6 3
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况,以及实现我在这里尝试的正确方法是什么?
(我需要使用因子而不是整数,以免混淆"01"和"1",我的原始数据集很大,所以使用因子而不是字符应该可以节省一些内存)
我认为实现您想要做的事情的一种方法是改变您的因素水平:
levels(df$var2)[!levels(df$var2) %in% sample] <- NA
Run Code Online (Sandbox Code Playgroud)
通过更改级别,所有与这些级别不匹配的值都将转换为因子 NA,结果将是:
df
var1 var2
1 1 01
2 2 24
3 3 <NA>
4 4 1
5 5 <NA>
6 6 24
> df$var2
[1] 01 24 <NA> 1 <NA> 24
Levels: 01 1 24
Run Code Online (Sandbox Code Playgroud)
未知值和无值不再位于因子水平中。或者,如果您想在您的价值观中保留未知和无,您可以尝试以下操作:
df$var2[!df$var2 %in% sample] <- NA
> df
var1 var2
1 1 01
2 2 24
3 3 <NA>
4 4 1
5 5 <NA>
6 6 24
> df$var2
[1] 01 24 <NA> 1 <NA> 24
Levels: 01 1 24 none unknown
Run Code Online (Sandbox Code Playgroud)
ifelse 更改数据类的原因是 ifelse 不维护类。在这里阅读第二个答案:如何防止 ifelse() 将 Date 对象转换为数字对象
@tchakravarty 在评论中提到的最后一种方法是使用 dplyr 中的 if_else!