'outer()' 函数中 'match.arg()' 的问题

Problem with 'match.arg()' inside 'outer()' function

Background/Problem

我正在尝试使用 outer() 函数将函数应用于两个向量的所有成对组合作为参数。在我的例子中,输入之一是一个字符向量,它应该作为一个内部函数 (cor()) 的参数,它需要 运行 match.arg() 就可以了。

示例 1(有效)

当内部函数不需要它时,这很好用,例如 paste()

# define function to test
f1 <- function(method, vec_len){
  paste(method, vec_len)
}

# define inputs to test
methods <- c("pearson", "spearman", "kendall")
vec_lens <- 33:35

# outer runs fine
outer(methods, vec_lens, f1)
#>      [,1]          [,2]          [,3]         
#> [1,] "pearson 33"  "pearson 34"  "pearson 35" 
#> [2,] "spearman 33" "spearman 34" "spearman 35"
#> [3,] "kendall 33"  "kendall 34"  "kendall 35"

示例 2(不起作用)

然而,当内部函数需要 运行 match.arg() 输入时,这会失败:

# function that parses string with match.arg fails
f2 <- function(method, vec_len){
  x <- runif(vec_len, 0, 10)
  y <- x + rnorm(vec_len)
  
  cor(x, y, method = method)
}

# outer fails on match.arg within cor()
outer(methods, vec_lens, f2)
#> Error in match.arg(method): 'arg' must be of length 1

我的研究

从我所做的研究 (1, 2, 3) 看来,这可能与无法访问全局环境的内部函数的作用域有关,但我不确定也不相信知道如何修复它。


顺便说一句

我知道代码没问题,因为我可以通过循环得到结果:

# desired result by loop
out <- list()
for (method in methods) {
  for (j in seq_along(vec_lens)) {
    out[[method]][[j]] <- f2(method, vec_lens[j])
    names(out[[method]])[j] <- vec_lens[j]
  }
}
do.call(rbind, out)
#>          33        34        35       
#> pearson  0.9351946 0.9491004 0.9516057
#> spearman 0.9067513 0.9315508 0.9456583
#> kendall  0.8371212 0.8146168 0.7983193

我们可以用Vectorize

换行
set.seed(24)
outer(methods, vec_lens, FUN = Vectorize(f2))
       [,1]      [,2]      [,3]
[1,] 0.9060101 0.9661931 0.9572807
[2,] 0.9542112 0.9495798 0.9490196
[3,] 0.8863636 0.8680927 0.7983193

给出与 for 循环相同的输出(dimnames 除外)

> set.seed(24)
> out <- list()
> for (method in methods) {
+   for (j in seq_along(vec_lens)) {
+     out[[method]][[j]] <- f2(method, vec_lens[j])
+     names(out[[method]])[j] <- vec_lens[j]
+   }
+ }
> do.call(rbind, out)
         33        34        35       
pearson  0.9060101 0.9309473 0.9637686
spearman 0.9532086 0.9254393 0.9526611
kendall  0.8257576 0.8074866 0.7983193