3

这似乎是一个愚蠢的问题,但对于我的生活我无法弄清楚所以感谢任何帮助。

我正在尝试将 .x(来自 purrr::map)传递给一个函数,所以最后我得到了一个函数列表(我最终将使用它来传递一个列定义列表,其中包含可反应的函数)。这是我想做的一个非常基本的例子:

a = list("b", "c")

t <- map(a, ~{
  function(.x){
    print(x)
  }
})

我正在寻找的结果是:

> t
[[1]]
function(b){
    print(x)
  }

[[2]]
function(c){
    print(x)
  }

但我得到:

> t
[[1]]
function(.x){
    print(x)
  }

[[2]]
function(.x){
    print(x)
  }

我正在寻找的可能吗?

4

1 回答 1

3

您可以通过使用包装函数创建新函数来获得所需的内容。在包装器中,创建一个空函数,将 args 设置为x传入的值(因此 if x="a", with 等价于alist(a=)),然后还将字符串解析为正文。然后返回的列表将是您想要的功能。

library(purrr)

function_crafter <- function(x) {
  f <- function() {}
  args <- setNames(list(bquote()), x)
  formals(f) <- args
  body(f) <- parse(text = paste0("print(", x, ")"))
  f
}

a <- list("b", "c")

fl <- map(a, function_crafter)

fl[[1]](b=2)
#> [1] 2
fl[[2]](c=39)
#> [1] 39

fl
#> [[1]]
#> function (b) 
#> print(b)
#> <environment: 0x7fb68752aae0>
#> 
#> [[2]]
#> function (c) 
#> print(c)
#> <environment: 0x7fb687552818>

如果您实际上希望print()每个函数中的 in 简单地是print(x)而不是print(b)or print(c),那么这更容易,只需在其初始化中定义函数的主体即可。

于 2022-02-12T13:09:24.387 回答