我正在阅读http://adv-r.had.co.nz/Functionals.html上的Hadley的AdvancedR。他谈论了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)当我将character(1)替换为character(2)时,它给我以下错误消息:
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。非常感谢您的想法。
最佳答案
问题1:character(2)
的错误是因为字符 vector "integer"
仅长度为1,并且正确地未能针对长度为2的字符 vector 的预期结果进行一致性检查。
问题2:vapply()
以safer version of sapply()
的形式存在,因为它确保您只能从FUN
的每个应用程序中获得期望的结果。我猜这也更安全,因为vapply()
的输出是一致的-您没有 vector ,矩阵或列表。您将获得长度为1的返回子组件的 vector ,否则将为数组。
在您提供的特定示例中,您不能使用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()
。关于r - 使用vapply而不是sapply,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43504174/