首页 > 解决方案 > R:硬编码函数内变量的内容

问题描述

我想使用存储在变量中的值创建一个函数,但是我粘贴该变量的“内容”而不是变量调用,这样一旦重新分配变量,函数就不会改变。

有没有一种优雅的方式来做到这一点?

var <- 3
f <- function(x) var + x

f(1)
#> [1] 4

var <- 1

f(1)  # I would like the output to stay the same, i.e., the function to be "fixed" after its creation
#> [1] 2

reprex 包于 2021-06-08 创建(v1.0.0)

标签: rfunctionnamespacesnse

解决方案


在 R 中,您将使用其中一种方法创建一个闭包。您可以定义一个本地环境并var在那里复制

f <- local({var; function(x) var + x})

或者你可以用一个内联函数做类似的事情

f <- local({var; function(x) var + x})

或者您可以将该版本拆分为生成器函数

make_f <- function(var) function(x) var + x
f <- make_f(var)

所有这些都会冻结var函数内部的值f

您还可以编写一个对环境创建更明确的辅助函数

freeze_var <- function(fun, ..., .env=environment(fun)) {
  mc <- match.call(expand.dots = FALSE)
  dnames <- sapply(mc$..., deparse)
  fenv <- new.env(parent=.env)
  list2env(setNames(list(...), dnames), envir = fenv)
  environment(fun) <- fenv
  fun
}

然后你可以用它来包装任何带有任何变量的函数

var <- 3
f <- function(x) var + x
ff <- freeze_var(f, var)

f(1)
# [1] 4
ff(1)
# [1] 4

var <- 1
f(1)
# [1] 2
ff(1)
# [1] 4

推荐阅读