为什么应用将数据帧中的逻辑转换为5个字符的字符串?

时间:2014-09-15 18:06:39

标签: r dataframe apply

假设我有一个数据框:

mydf <- data.frame(colA = c(1,20), colB = c("a", "ab"), colC = c(T, F))

现在假设我想将一个函数应用于数据框的每一行。此函数使用列C的布尔值。使用apply时,每个非字符串都将转换为列中存在的最大长度的字符串:

> apply(mydf, 1, '[', 3)
[1] " TRUE" "FALSE"

字符串" TRUE"不再可解释为逻辑。

> ifelse(apply(mydf, 1, '[', 3), 1, 2)
[1] NA  2

我可以用gsub(" ", "", x)解决这个问题,但我敢打赌,有更好的方法。为什么apply只能直接将逻辑转换为字符串时会出现这种行为?是否有类似apply的函数,它没有上述行为?

2 个答案:

答案 0 :(得分:3)

当您致电apply时,您的数据框已转换为字符矩阵。出现这些空格是因为每个元素都转换为列中最宽元素的宽度。

您可以使用for类似循环的sapply来电

进行此操作
> ( s <- sapply(seq(nrow(mydf)), function(i) mydf[i, 3]) )
# [1]  TRUE FALSE
> class(s)
# [1] "logical"

使用apply执行操作的解决方法是

> as.logical(gsub("\\s+", "", apply(mydf, 1, `[`, 3)))
# [1]  TRUE FALSE

但请注意,这些都与

完全相同
> mydf[,3]
# [1]  TRUE FALSE

答案 1 :(得分:1)

apply无法直接使用data.frames;它适用于矩阵和矩阵,所有元素必须是相同的原子类型。如果您传入data.frame,apply()会将其强制转换为矩阵。由于字符值无法以更“简单”的数据类型存储,因此所有内容都会转换为字符值。

通常,您没有考虑过一次将函数应用于data.frame的行。大多数情况下,您可以使用data.frame列中的基本向量函数来完成您想要完成的任务。如果你想要

ifelse(apply(mydf, 1, '[', 3), 1, 2)

尝试

ifelse(mydf[, 3], 1, 2)

代替