R:apply()中的错误?
我在使用apply()时出现了一些奇怪的行为。我试图创建一个逻辑向量来指示给定的列是否是伪变量(只有0和1个值)。只要所有非NA值均为0或1,丢失值仍应视为伪值 如果所讨论的数据帧仅包含数值,则我的代码可以正常工作。 但是,如果数据框还包含字符串列,则该函数不再忽略NA值,即使在检查以前有效的数字列时也是如此 例如:R:apply()中的错误?,r,apply,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 = 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
这是因为
apply
将数据帧转换为矩阵,矩阵只能保存一种类型的值
看,
所以对于第一列,它实际上检查
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
这是因为
apply
将数据帧转换为矩阵,矩阵只能保存一种类型的值
看,
所以对于第一列,它实际上检查
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
我明白了,太棒了!我明白了,太棒了<代码>应用应与类似数组的对象一起使用。对于
data.frames
,如果要对每列应用函数,请使用lappy
(或vapply
)。或作为黄金会员,警告新用户:1。如果您正在使用data.frames,请忘记有一个名为apply的函数-无论您做什么-不要使用它。特别是边距为1(此函数的唯一良好用途是在矩阵列上操作-边距为2)。apply
应与类似array
的对象一起使用。对于data.frames
,如果要对每列应用函数,请使用lappy
(或vapply
)。或作为黄金会员,警告新用户:1。如果您正在使用data.frames,请忘记有一个名为apply的函数-无论您做什么-不要使用它。特别是当边距为1时(此函数的唯一好用法是在矩阵列上操作-边距为2)。