gpt4 book ai didi

r - 为什么 `vapply` 比 `sapply` 更安全?

转载 作者:行者123 更新时间:2023-12-02 05:31:41 26 4
gpt4 key购买 nike

文档说

vapply is similar to sapply, but has a pre-specified type of return value, so it can be safer [...] to use.

您能否详细说明为什么它通常更安全,也许可以提供示例?

<小时/>

P.S.:我知道答案,并且我已经倾向于避免 sapply。我只是希望这里有一个很好的答案,这样我就可以向我的同事指出它。请不要回答“阅读手册”。

最佳答案

正如已经指出的,vapply 做了两件事:

  • 速度略有提高
  • 通过提供有限的返回类型检查来提高一致性。

第二点是更大的优势,因为它有助于在错误发生之前捕获错误并导致更健壮的代码。此返回值检查可以单独完成,方法是使用 sapply 后跟 stopifnot 以确保返回值与您的预期一致,但 vapply > 更容易一些(如果有更多限制,因为自定义错误检查代码可以检查边界内的值等)。

这是一个 vapply 的示例,可确保您的结果符合预期。这与我在 PDF 抓取时所做的事情类似,其中 findD 将使用 来匹配原始文本数据中的模式(例如,我有一个按实体分割的列表,以及一个正则表达式来匹配每个实体内的地址。有时 PDF 会被乱序转换并且一个实体会有两个地址,这会导致不良情况)。

> input1 <- list( letters[1:5], letters[3:12], letters[c(5,2,4,7,1)] )
> input2 <- list( letters[1:5], letters[3:12], letters[c(2,5,4,7,15,4)] )
> findD <- function(x) x[x=="d"]
> sapply(input1, findD )
[1] "d" "d" "d"
> sapply(input2, findD )
[[1]]
[1] "d"

[[2]]
[1] "d"

[[3]]
[1] "d" "d"

> vapply(input1, findD, "" )
[1] "d" "d" "d"
> vapply(input2, findD, "" )
Error in vapply(input2, findD, "") : values must be length 1,
but FUN(X[[3]]) result is length 2

因为 input2 的第三个元素中有两个 d,所以 vapply 会产生错误。但是 sapply 将输出的类从字符向量更改为列表,这可能会破坏下游代码。

正如我告诉我的学生的那样,成为一名程序员的一部分就是将你的心态从“错误很烦人”转变为“错误是我的 friend 。”

零长度输入
一个相关点是,如果输入长度为零,则无论输入类型如何,sapply 都将始终返回一个空列表。比较:

sapply(1:5, identity)
## [1] 1 2 3 4 5
sapply(integer(), identity)
## list()
vapply(1:5, identity, integer(1))
## [1] 1 2 3 4 5
vapply(integer(), identity, integer(1))
## integer(0)

使用vapply,您可以保证获得特定类型的输出,因此您无需为零长度输入编写额外的检查。

基准

vapply 可能会快一点,因为它已经知道预期结果应采用什么格式。

input1.long <- rep(input1,10000)

library(microbenchmark)
m <- microbenchmark(
sapply(input1.long, findD ),
vapply(input1.long, findD, "" )
)
library(ggplot2)
library(taRifx) # autoplot.microbenchmark is moving to the microbenchmark package in the next release so this should be unnecessary soon
autoplot(m)

autoplot

关于r - 为什么 `vapply` 比 `sapply` 更安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12339650/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com