【问题标题】:Factor variable coerced into character when replacing NA with a number using apply()使用 apply() 将 NA 替换为数字时强制转换为字符的因子变量
【发布时间】:2019-02-14 16:06:11
【问题描述】:

在尝试用数字 9 替换多个因子变量的 NA 时,我注意到 apply() 的一种特殊行为。我已经定义了这些变量的级别和标签。当我对每个变量单独使用 ifelse() 时(例如 ifelse(is.na(x),9,x),它会将变量强制转换为整数,这是可以理解的。但是,当我创建一个函数来执行完全相同的操作时在多列上使用 apply(),它将所有变量强制转换为字符。再添加一个步骤将它们转换回函数中的因子无济于事。我错过了什么或者 apply() 函数有什么奇怪的地方吗?谢谢!

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(a,b)
replace.na<-function(x){
    x<-as.factor(ifelse(is.na(x),9,x))
}
a<-ifelse(is.na(a),9,a)
str(a)
dat<-apply(dat,2,replace.na)
str(dat)

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

【问题讨论】:

  • R apply 函数通常返回一个矩阵,R 矩阵不能包含因子。所以这不是一种特殊的行为。这是一个设计特点。
  • 谢谢!我不知道。我会记住这一点。那么你会推荐 apply() 系列中的哪个函数呢?
  • 很难确切知道。 dat 对象也没有任何因子组件,因为您使用了 cbind

标签: r apply


【解决方案1】:

处理因素的一个主要困难是他们不能接受不在现有级别中的值的分配。您的示例没有说明这一点,因为您使用了 cbind ,它将因子强制为其基础整数值。因子实际上是具有级别属性的整数向量。如果您想获得一个可以接受现有级别之外的分配的结构,那么您有两种选择:1)使用as.character 转换因子或2)首先使用levels(fac) &lt;- 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" 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多