文档说



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

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

最佳答案

如前所述,vapply 做了两件事:

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

  • 第二点是更大的优势,因为它有助于在错误发生之前捕获错误并导致更健壮的代码。此返回值检查可以通过使用 sapply 后跟 stopifnot 来单独完成,以确保返回值与您预期的一致,但 vapply 更容易一些(如果更多限制,因为自定义错误检查代码范围内的值可以检查, 等等。)。
    这是 vapply 的示例,确保您的结果符合预期。这与我刚刚在 PDF 抓取时正在处理的事情相似,其中 findD 将使用 regex 来匹配原始文本数据中的模式(例如,我有一个列表,该列表是 split 实体,并匹配每个实体中的 reg 地址。有时,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)
    
    r - 为什么  `vapply` 比  `sapply` 更安全?-LMLPHP

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

    10-13 00:31