我正在阅读位于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)
Run Code Online (Sandbox Code Playgroud)
这返回
$x
[1] "integer"
$y
[1] "POSIXct" "POSIXt"
Run Code Online (Sandbox Code Playgroud)
但是,当我运行时vapply,出现错误。
vapply(df2, class, character(1))
Run Code Online (Sandbox Code Playgroud)
错误:
Error in vapply(df2, class, character(1)) : values must be length 1,
but FUN(X[[2]]) result is length 2
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
问题:1)当我用character(2)替换character(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
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
问题:2)我该如何vapply代替sapply?
我正在学习R,因此您的答案将帮助我更深入地了解R。非常感谢您的想法。
出现错误character(2)的原因是,字符向量"integer"仅具有长度1,并且正确地未能针对长度为2的字符向量的预期结果进行一致性检查。
vapply()是的更安全版本,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"
Run Code Online (Sandbox Code Playgroud)
但是那对您有用还是另一回事。
的确,使用vapply()归结为知道从中FUN得到什么,并且只想获得该输出。如果您不知道或无法控制它,最好使用lapply()。