我试图优化代码,并想使用 vapply
的 .Internal
实现,但出现了一个我不明白的错误。 (现在我会认真对待 ?.Internal
的警告,即“只有真正的 R 向导才应该考虑使用此函数”并使用用户可见的 vapply
但我尽管如此,我还是想更好地理解这个错误。)
test <- rnorm(10000)
test_l <- as.list(test)
test_2 <- .Internal(vapply(test_l, \(x) x^2, numeric(1), FALSE))
# Error: '...' used in an incorrect context
将此与用户可见的代码进行比较vapply
:
function (X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(vapply(X, FUN, FUN.VALUE, USE.NAMES))
}
有人可以向我解释一下为什么这不起作用吗?
我的一些假设:
它是否在用户可见的函数体 vapply
之外的另一个命名空间中运行,或者我是否出于其他原因调用用户可见的函数而不是 .Internal
?
是否因为内部vapply
是一个特殊的内部,其工作方式与其他内部不同?
R-ints 手册 [1] 指出:
2.2 Special internals
There are also special .Internal functions: NextMethod, Recall, withVisible, cbind, rbind (to allow for the deparse.level argument), eapply, lapply and vapply.
但没有提供更多细节。
有人可以告诉我有关“特殊内部结构”的更多详细信息吗?
[1] https://cran.r-project.org/doc/manuals/R-ints.html#g_t_002eInternal-vs-_002ePrimitive
最佳答案
C code指的是R_DotsSymbol
,即省略号。调用范围没有省略号。它不能,因为它不是函数调用。
您可以使用标准 R 代码重现错误,如下所示:
foo <- function() {
return(...)
}
foo()
#Error in foo() : '...' used in an incorrect context
或者使用.Internal
调用vapply
,如下所示:
bar <- function(X, FUN, FUN.VALUE, USE.NAMES) {
.Internal(vapply(X, FUN, FUN.VALUE, USE.NAMES))
}
bar(test_l, \(x) x^2, numeric(1), FALSE)
#Error in bar(test_l, function(x) x^2, numeric(1), FALSE) :
# '...' used in an incorrect context
这是有效的,因为 ...
存在于调用范围中:
baz <- function(X, FUN, FUN.VALUE, USE.NAMES, ...) {
.Internal(vapply(X, FUN, FUN.VALUE, USE.NAMES))
}
x <- baz(test_l, \(x) x^2, numeric(1), FALSE)
跳过 vapply
的前几行,您将无法生成速度明显更快的代码。他们不是你的瓶颈。它可能有助于使用 Rcpp 实现 vapply
重复调用的函数,但只有使用 Rcpp 实现整个循环才能实现真正的性能提升。对 R 闭包的调用非常昂贵,您希望在具有多次迭代的循环中避免它们。
关于r - 尝试使用内部函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74361130/