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