该文件说,
vapply
类似于sapply
,但有一个预先指定的返回值的类型,所以可以更安全[...]使用。
你能否透露细节,为什么它通常是安全的,也许提供的例子吗?
PS:我知道答案,我已经倾向于避免sapply
。 我只是希望有离开SO所以我可以指出我的同事给它一个很好的答案。 请,没有“阅读手册”的答案。
该文件说,
vapply
类似于sapply
,但有一个预先指定的返回值的类型,所以可以更安全[...]使用。
你能否透露细节,为什么它通常是安全的,也许提供的例子吗?
PS:我知道答案,我已经倾向于避免sapply
。 我只是希望有离开SO所以我可以指出我的同事给它一个很好的答案。 请,没有“阅读手册”的答案。
正如已经指出的那样, vapply
做两件事情:
第二点是更大的优势,因为它可以帮助捕捉错误发生之前,并导致更健壮的代码。 这个返回值检查可以单独使用来完成sapply
随后stopifnot
以确保返回值与你所期望的一致,但vapply
相对容易一些(如果较为有限,因为自定义错误校验码可能范围内检查值等)。
下面是一个例子vapply
确保你的结果是如预期。 这种平行的东西,我只是工作,而上刮PDF,其中findD
将使用正则表达式来匹配原始文本数据的模式(例如我不得不说是一个列表split
的实体,和一个正则表达式的每个实体内匹配的地址。有时,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
当我告诉我的学生,成为一名程序员的部分是改变你的心态从“错误是烦人”到“错误是我的朋友。”
零级长度的输入
一个相关的问题是,如果输入的长度为零, sapply
总是会返回一个空列表,无论输入型的。 相比:
sapply(1:5, identity)
## [1] 1 2 3 4 5
sapply(integer(), identity)
## list()
vapply(1:5, identity)
## [1] 1 2 3 4 5
vapply(integer(), identity)
## 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)
涉及额外的击键vapply
可以节省您的时间后,调试混乱的结果。 如果你调用该函数可以返回不同的数据类型, vapply
当然应该使用。
我想到的一个例子就是sqlQuery
在RODBC
包。 如果有执行查询时出现错误,这个函数返回一个character
与信息载体。 因此,举例来说,假设你正在试图遍历表名称的矢量tnames
,然后从每个表中与数字列“NumCol”的最大值:
sapply(tnames,
function(tname) sqlQuery(cnxn, paste("SELECT MAX(NumCol) FROM", tname))[[1]])
如果所有的表名是有效的,这将导致一个numeric
矢量。 但是,如果表名称中的一个发生在数据库中更改和查询失败,结果会被强迫模式character
。 使用vapply
与FUN.VALUE=numeric(1)
但是,将停在这里的误差,并防止它从什么地方突然出现上下行---或者更糟,根本没有。
如果你总是希望你的结果是什么特别......例如,逻辑载体。 vapply
确保这种情况发生,但sapply
并不一定这样做。
a<-vapply(NULL, is.factor, FUN.VALUE=logical(1))
b<-sapply(NULL, is.factor)
is.logical(a)
is.logical(b)