R:硬编码函数内部变量的内容
R: hard code the content of a variable inside a function
我想使用存储在变量中的值创建一个函数,但我会粘贴该变量的“内容”而不是变量调用,这样一旦变量被重新分配,功能不变。
有什么优雅的方法吗?
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 package (v1.0.0)
于 2021-06-08 创建
在 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)
所有这些都会在函数f
.
中冻结var
的值
您还可以编写一个更明确地说明环境创建的辅助函数
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
你可以计算语言:
var <- 3
f <- function(x) var + x
body(f)[[2]] <- var
f
#function (x)
#3 + x
f(1)
#> [1] 4
var <- 1
f(1)
#[1] 4
我不太确定输出保持不变是什么意思:
我们可以这样做:
f <- local({
a <- new.env()
if(!exists('z', a)) a$z<-var
function(x)x+a$z})
var <- 3
f(1)
#[1] 4
var <- 1
f(1)
#[1] 4 # Did not change (BUT WHY WOULD YOU WANT THIS BEHAVIOUR?)
为什么你想要相同的输出?您宁愿在函数
中使用值 3
f <- function(x) x + 3
甚至锁定变量以防止对其进行任何更改。即对变量的任何更改都会引发错误
var <- 3
lockBinding('var', globalenv())
f <- function(x) x + var
var <- 1# will throw an error.
我想使用存储在变量中的值创建一个函数,但我会粘贴该变量的“内容”而不是变量调用,这样一旦变量被重新分配,功能不变。
有什么优雅的方法吗?
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 package (v1.0.0)
于 2021-06-08 创建在 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)
所有这些都会在函数f
.
var
的值
您还可以编写一个更明确地说明环境创建的辅助函数
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
你可以计算语言:
var <- 3
f <- function(x) var + x
body(f)[[2]] <- var
f
#function (x)
#3 + x
f(1)
#> [1] 4
var <- 1
f(1)
#[1] 4
我不太确定输出保持不变是什么意思:
我们可以这样做:
f <- local({
a <- new.env()
if(!exists('z', a)) a$z<-var
function(x)x+a$z})
var <- 3
f(1)
#[1] 4
var <- 1
f(1)
#[1] 4 # Did not change (BUT WHY WOULD YOU WANT THIS BEHAVIOUR?)
为什么你想要相同的输出?您宁愿在函数
中使用值 3f <- function(x) x + 3
甚至锁定变量以防止对其进行任何更改。即对变量的任何更改都会引发错误
var <- 3
lockBinding('var', globalenv())
f <- function(x) x + var
var <- 1# will throw an error.