我正在http://adv-r.had.co.nz/Functionals.html阅读Hadley的Advanced R。他谈到了sapply
和vapply
之间的区别。我的问题与使用vapply
代替sapply
有关,在他的例子中他没有进一步讨论。
这是他的代码:
df2 <- data.frame(x = 1:10, y = Sys.time() + 1:10)
sapply(df2, class)
返回
$x
[1] "integer"
$y
[1] "POSIXct" "POSIXt"
但是,当我运行vapply
时,我收到错误消息。
vapply(df2, class, character(1))
错误:
Error in vapply(df2, class, character(1)) : values must be length 1,
but FUN(X[[2]]) result is length 2
我有两个问题:
问题:1)当我用字符(2)替换字符(1)时,它会给我以下错误消息:
vapply(df2, class, character(2))
Error in vapply(df2, class, character(2)) : values must be length 2,
but FUN(X[[1]]) result is length 1
为什么会这样?
问题:2)如何使用vapply
代替sapply
?
我正在学习R所以你的答案将帮助我更深入地理解R.我很感激你的想法。
答案 0 :(得分:4)
character(2)
的错误是因为字符向量"integer"
的长度仅为1,并且正确地不能对长度为2的字符向量的预期结果进行一致性检查。
vapply()
作为safer version of sapply()
存在,因为它确保您只返回对FUN
的每个应用程序的期望。我猜也更安全,因为vapply()
的输出是一致的 - 你不会得到一个向量,一个矩阵或一个列表。您将获得长度为1的返回子组件的向量,否则为一个数组。
在您提供的具体示例中,您无法使用vapply()
,因为class
返回的内容并非一致。如果调用vapply()
的输出与预期不符,您必须知道或预期某些输出会FUN
失败。
在这种情况下,我想你可以做到
df2 <- data.frame(x = 1:10, y = Sys.time() + 1:10)
vapply(df2, FUN = function(x) paste(class(x), collapse = "; "),
FUN.VALUE = character(1))
> vapply(df2, FUN = function(x) paste(class(x), collapse = "; "),
+ FUN.VALUE = character(1))
x y
"integer" "POSIXct; POSIXt"
但是否对你有用是另一回事。
真的,使用vapply()
归结为知道FUN
会发生什么,并希望只获得该输出。如果您不知道或无法控制它,那么lapply()
可能会更好。