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 package (v1.0.0) 于 2021 年 6 月 8 日创建

解决方法

在 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
,

您可以根据语言进行计算:

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.

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...