使用apply()将NA替换为数字时,因子变量被强制转换为字符

时间:2019-02-14 16:06:11

标签: r apply

当多因素变量试图用数字9替换NA时,我注意到了apply()的一种特殊行为。我已经定义了这些变量的级别和标签。当我分别对每个变量使用ifelse()时(例如ifelse(is.na(x),9,x)),它将变量强制转换为整数,这是可以理解的。但是,当我创建一个函数以使其完全相同时,在多列上使用apply(),它将所有变量都强制转换为字符,再增加一步将它们转换回函数中的值无济于事,我是否错过了某些事情,或者apply()函数有点奇怪?

{{1}}

我希望apply()会产生相同类型的变量,或者至少在函数中使用as.factor()会将变量强制为一个因子。

1 个答案:

答案 0 :(得分:0)

处理因素的主要困难是它们不能接受不属于现有水平的值的赋值。您的示例未举例说明,因为您使用了cbind强制将因子转换为其基础整数值。因子实际上是具有level属性的整数向量。如果要获得一个可以接受现有级别之外的分配的结构,则有两个选择:1)用as.character转换因子或2)首先用levels(fac) <- c(levels(fac), new_values)增强因子级别。

由于您要处理矩阵中的多个列,因此我认为最好在使用cbind之前使用转换为字符的第一个选项。

 a<-c(1,2,3,NA,2)
 b<-c(2,1,2,2,NA)
 a<-factor(a,levels=c(1,2,3),labels=c("First","Second","Third"))
 b<-factor(b,levels=c(1,2,3), labels=c("AA","BB","CC"))
 dat<-cbind( as.character(a), as.character(b))
 replace.na<-function(x){
     x<-as.factor(ifelse(is.na(x), 9, x))
 }
 a<-ifelse(is.na(a),9,a)
 str(a)
num [1:5] 1 2 3 9 2    #shows the underlying numeric values after changing `a`
 dat<-apply(dat,2,replace.na)
 str(dat)             # the dat object was not affected by the second modification of `a`
chr [1:5, 1:2] "First" "Second" "Third" "9" "Second" "BB" "AA" "BB" "BB" ...
dat
#---------------
     [,1]     [,2]
[1,] "First"  "BB"
[2,] "Second" "AA"
[3,] "Third"  "BB"
[4,] "9"      "BB"
[5,] "Second" "9"