首页 > 解决方案 > R:apply() 中的错误?

问题描述

使用 apply() 时出现一些奇怪的行为。我正在尝试创建一个逻辑向量来指示给定列是否是虚拟变量(只有 0 和 1 值)。只要所有非 NA 值都是 0 或 1,缺失值仍应视为虚拟变量。

如果有问题的数据框只包含数值,我的代码可以正常工作。但是,如果数据框还包含一个字符串列,则该函数不再忽略 NA 值,即使在检查以前工作的数字列时也是如此。

例子:

x1 = c(1,0,1,NA)
x2 = c(1,1,0,1)
x3 = c(1,2,3,4)
x4 = c('a','b','c','d')
dat1 = data.frame(x1,x2,x3)
dat2 = data.frame(x1,x2,x3,x4)
isdum1 = apply(dat1,2,function(x) {all(x %in% c(0:1,NA))})
isdum2 = apply(dat2,2,function(x) {all(x %in% c(0:1,NA))})

isdum1   # works fine
   x1    x2    x3 
 TRUE  TRUE FALSE 
isdum2   # wtf?
   x1    x2    x3    x4 
FALSE  TRUE FALSE FALSE 

标签: rapply

解决方案


那是因为apply将数据框转换为矩阵并且矩阵只能保存一种类型的值。

看,

apply(dat1, 2, class)
#    x1        x2        x3 
#"numeric" "numeric" "numeric" 

apply(dat2, 2, class)
#      x1          x2          x3          x4 
#"character" "character" "character" "character" 

所以对于第一列它实际上检查

all(c("1", "0", "1", "NA") %in% c(0:1,NA))
#[1] FALSE

因此,答案。

您可以改为使用sapplywhich 也按列操作而不更改类。

sapply(dat1, function(x) {all(x %in% c(0:1,NA))})
#   x1    x2    x3 
# TRUE  TRUE FALSE 

sapply(dat2, function(x) {all(x %in% c(0:1,NA))})
#   x1    x2    x3    x4 
# TRUE  TRUE FALSE FALSE 

推荐阅读