通过将函数列表应用于参数列表来创建列表的 R 惯用方法是什么?
例如,给定一个函数列表和一个参数列表,数量相等(比如三个),
fncs <- list(f1, f2, f3)
args <- list(x1, x2, x3)
Run Code Online (Sandbox Code Playgroud)
我想获取函数值列表,
fnc_vals <- list(f1(x1), f2(x2), f3(x3))
Run Code Online (Sandbox Code Playgroud)
换句话说,我想将 base-R 函数的广义形式应用于mapply列表fncs和args(将单个函数应用于参数列表)。
这很容易做到:
dapply <- function(args, fncs, ...) { # "diagonal" apply
lapply(seq_along(args), function(i) fncs[[i]](args[[i]], ...))
}
fnc_vals <- dapply(args, fncs)
Run Code Online (Sandbox Code Playgroud)
然而,在我看来,这很笨拙,因为如果在 R 中可能,没有扭曲,成对运行函数和参数以生成所需的函数值列表会更自然;在Python 中,这会是这样的:
fncs = [f1, f2, f3]
args = [x1, x2, x3]
fnc_vals = [f(x) for f, x in zip(fncs, args)]
Run Code Online (Sandbox Code Playgroud)
这个“zippy”结构也可以在 R 中实现吗?
您可以使用Map(mapply具有不同的默认值)与do.call:
fncs <- list(mean, median, sd)
args <- list(1:5, 11:13, c(1,1,1,2))
Map(function(f, x) do.call(f, list(x)), fncs, args)
#[[1]]
#[1] 3
#
#[[2]]
#[1] 12
#
#[[3]]
#[1] 0.5
Run Code Online (Sandbox Code Playgroud)
匿名函数是必要的,因为它的第二个参数do.call需要 a list。
或者因为无论如何你都编写了一个匿名函数,你可以Map(function(f, x) f(x), fncs, args)像@akrun 指出的那样使用。