R:评估多个和不同变化的参数的函数
R: Evaluate function for multiple and differently-changing arguments
我有一个有 4 个参数的函数:
my.function <- function(w,x,y,z){
w + x + y + z
}
我可以给这个函数多个值 z
:
> my.function(1,1,1,1:5)
[1] 4 5 6 7 8
但是,如果我想为函数提供 w,x,y
的值列表和 z
的值向量,这样函数将计算 [=] 的每个 set
17=] 与 z
?
的每个元素
wxy.args <- list(set1 = list(w = 1.1, x = 2.1, y = 3.1),
set2 = list(w = 1.2, x = 2.2, y = 3.3),
set3 = list(w = 1.3, x = 2.3, y = 3.3))
z <- 1:5
理想情况下,我希望得到一个 n x m
矩阵,其中 n = set
和 m = z
。因此,我想使用 outer()
、but it doesn't seem like that is possible.
所以,我想这将涉及 apply family 之一或 apply 和 do.call 的某种组合,但我正在努力解决它。
提前致谢!
一个选项可以是:
sapply(z, function(x) lapply(wxy.args, function(y) sum(unlist(y), x)))
[,1] [,2] [,3] [,4] [,5]
set1 7.3 8.3 9.3 10.3 11.3
set2 7.7 8.7 9.7 10.7 11.7
set3 7.9 8.9 9.9 10.9 11.9
library(purrr)
wxy.args %>% map(~c(.x, z = list(z))) %>%
map(~do.call("my.function", args = .x)) %>%
unlist() %>%
matrix(nrow = length(wxy.args), byrow = TRUE)
给出:
[,1] [,2] [,3] [,4] [,5]
[1,] 7.3 8.3 9.3 10.3 11.3
[2,] 7.7 8.7 9.7 10.7 11.7
[3,] 7.9 8.9 9.9 10.9 11.9
您可以使用 mapply
迭代您的集合。它遍历列表元素。我使用 do.call
将子列表传递给 my.function
:
mapply(function(...) do.call(my.function, c(list(z = z), ...)),
wxy.args)
# set1 set2 set3
#[1,] 7.3 7.7 7.9
#[2,] 8.3 8.7 8.9
#[3,] 9.3 9.7 9.9
#[4,] 10.3 10.7 10.9
#[5,] 11.3 11.7 11.9
必要时使用t
转置矩阵。
要使用 outer
定义 my.function2
,my.function
的一个版本,将 z
和 wxy
作为两个单独的参数,然后传递矢量化它的版本为 outer
:
my.function2 <- function(z, wxy) do.call(my.function, c(wxy, z))
outer(z, wxy.args, Vectorize(my.function2))
给予:
set1 set2 set3
[1,] 7.3 7.7 7.9
[2,] 8.3 8.7 8.9
[3,] 9.3 9.7 9.9
[4,] 10.3 10.7 10.9
[5,] 11.3 11.7 11.9
另一种更简单但稍微乏味的等效可能性是使用此版本的 my.function2
写出 my.function
的参数:
my.function2 <- function(z, wxy) my.function(wxy[[1]], wxy[[2]], wxy[[3]], z)
我有一个有 4 个参数的函数:
my.function <- function(w,x,y,z){
w + x + y + z
}
我可以给这个函数多个值 z
:
> my.function(1,1,1,1:5)
[1] 4 5 6 7 8
但是,如果我想为函数提供 w,x,y
的值列表和 z
的值向量,这样函数将计算 [=] 的每个 set
17=] 与 z
?
wxy.args <- list(set1 = list(w = 1.1, x = 2.1, y = 3.1),
set2 = list(w = 1.2, x = 2.2, y = 3.3),
set3 = list(w = 1.3, x = 2.3, y = 3.3))
z <- 1:5
理想情况下,我希望得到一个 n x m
矩阵,其中 n = set
和 m = z
。因此,我想使用 outer()
、but it doesn't seem like that is possible.
所以,我想这将涉及 apply family 之一或 apply 和 do.call 的某种组合,但我正在努力解决它。
提前致谢!
一个选项可以是:
sapply(z, function(x) lapply(wxy.args, function(y) sum(unlist(y), x)))
[,1] [,2] [,3] [,4] [,5]
set1 7.3 8.3 9.3 10.3 11.3
set2 7.7 8.7 9.7 10.7 11.7
set3 7.9 8.9 9.9 10.9 11.9
library(purrr)
wxy.args %>% map(~c(.x, z = list(z))) %>%
map(~do.call("my.function", args = .x)) %>%
unlist() %>%
matrix(nrow = length(wxy.args), byrow = TRUE)
给出:
[,1] [,2] [,3] [,4] [,5]
[1,] 7.3 8.3 9.3 10.3 11.3
[2,] 7.7 8.7 9.7 10.7 11.7
[3,] 7.9 8.9 9.9 10.9 11.9
您可以使用 mapply
迭代您的集合。它遍历列表元素。我使用 do.call
将子列表传递给 my.function
:
mapply(function(...) do.call(my.function, c(list(z = z), ...)),
wxy.args)
# set1 set2 set3
#[1,] 7.3 7.7 7.9
#[2,] 8.3 8.7 8.9
#[3,] 9.3 9.7 9.9
#[4,] 10.3 10.7 10.9
#[5,] 11.3 11.7 11.9
必要时使用t
转置矩阵。
要使用 outer
定义 my.function2
,my.function
的一个版本,将 z
和 wxy
作为两个单独的参数,然后传递矢量化它的版本为 outer
:
my.function2 <- function(z, wxy) do.call(my.function, c(wxy, z))
outer(z, wxy.args, Vectorize(my.function2))
给予:
set1 set2 set3
[1,] 7.3 7.7 7.9
[2,] 8.3 8.7 8.9
[3,] 9.3 9.7 9.9
[4,] 10.3 10.7 10.9
[5,] 11.3 11.7 11.9
另一种更简单但稍微乏味的等效可能性是使用此版本的 my.function2
写出 my.function
的参数:
my.function2 <- function(z, wxy) my.function(wxy[[1]], wxy[[2]], wxy[[3]], z)