使用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
答案 0 :(得分:7)
这是因为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
因此,答案。
您可以改用sapply
,它也可以按列操作,而无需更改类。
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