r语言 - 函数内部'match.arg()' 'outer()'问题



背景/问题

我试图使用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(来看,这可能与内部功能无法访问全局环境的范围有关,但我不确定也不知道如何解决


BTW

我知道代码很好,因为我可以通过循环得到结果:

# 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

最新更新