R,函数内的按值传递
R, pass-by-value inside a function
假设您使用以下代码在 R 中定义一个函数:
a <- 1
f <- function(x) x + a
如果您稍后重新定义 a
,您将更改函数 f。 (所以,f(1) = 2
是给定的,但如果你稍后重新定义 a =2
,那么 f(1) = 3
。有没有办法强制 R 在编译时使用 a
的值函数?(也就是说,f
不会随着 a
的后期重新定义而改变)。
以上是我能想到的最短的情况,体现了我遇到的问题。更具体地说,应要求,我的情况是:
我正在处理我正在调用的一堆对象 "person"。每个人都被定义为一个概率分布,该分布取决于一个 n 维向量 $a$ 和一个 n 维约束向量 w(财富份额)。
我想创建一个有 N 个人的 "society",即 N 个人的列表。为此,我创建了两个 n×N 矩阵 A 和 W。我现在循环 1 到 N 来创建个体。
Society <- list()
### doesn't evaluate theta at the time, but does w...
for (i in 1:Npeople) {
w <- WealthDist[i,]
u <- function(x) prod(x^A[i,])
P <- list(u,w)
names(P) <- c("objective","w")
Society[[length(Society)+1]] <- P
}
w gets 是按价值传递的,因此每个人都获得了适量的财富。但是 A 是按引用传递的——每个人都被分配了相同的函数 u(即使用 i = N 的函数)
为了完成它,接下来的步骤是获得协会,并通过两次优化获得 "equilibrium point"。
在 f
内定义 a
f <- function(x) {a<-1;x + a}
R 不通过引用传递;一切都按值传递给函数。正如您所注意到的,由于 a
是在全局环境中定义的,因此引用 a
的函数引用的是 a
的全局值,该值可能会发生变化。为确保使用a
的特定值,您可以将其用作函数中的参数。
f <- function(x, a = 1) {
x + a
}
这将a
定义为默认为1的参数。函数使用的a
的值将始终是传递给函数的值,无论a
在全局环境中定义。
如果您要使用 lapply()
,只需将 a
作为参数传递给 lapply()
。
lapply(X, f, a = <value>)
您可以创建一个使用锁定绑定的函数,并创建一个函数来完成您的目的。 a 的前值将用于 w
,它将存储在函数的环境中,并且不会被 a
.
的进一步值更改所取代
a <- 1
j <- new.env() # create a new environment
create.func <- function () {
j$w <<- a
function (x) {
x+ j$w
}
}
f <- create.func()
a <- 2
f(2)
[1] 3 # if w was changed this should be 4
致谢 Andrew Taylor(见评论)
编辑: 注意:如果你调用 create.func
,f 会改变,即使你没有将它存储到 f 中。为避免这种情况,您可以编写此代码(这显然取决于您想要什么)。
a <- 1
create.func <- function (x) {
j <- new.env()
j$w <- a
function (x) {
x + j$w
}
}
f <- create.func()
f(1)
[1] 2
a <- 2
q <- create.func()
q(1)
[1] 3
f(1)
[1] 2
编辑 2: 延迟求值不适用于此处,因为 a 是通过设置为 j$w
来求值的。如果您将其用作参数,请说:
function(a)
function(x)
#use a here
您必须在定义第二个函数之前使用 force
,因为那样它就不会被计算。
编辑 3: 我删除了 foo <-
等。该函数将在声明后立即 return,因为您希望它相似到您的 link.
中定义的代码工厂
由 OP 编辑只是为了添加到已接受的答案中,本着
Function Factory in R
下面的代码有效:
funs.gen <- function(n) {
force(n)
function(x) {
x + n
}
}
funs = list()
for (i in seq(length(names))) {
n = names[i]
funs[[n]] = funs.gen(i)
}
假设您使用以下代码在 R 中定义一个函数:
a <- 1
f <- function(x) x + a
如果您稍后重新定义 a
,您将更改函数 f。 (所以,f(1) = 2
是给定的,但如果你稍后重新定义 a =2
,那么 f(1) = 3
。有没有办法强制 R 在编译时使用 a
的值函数?(也就是说,f
不会随着 a
的后期重新定义而改变)。
以上是我能想到的最短的情况,体现了我遇到的问题。更具体地说,应要求,我的情况是:
我正在处理我正在调用的一堆对象 "person"。每个人都被定义为一个概率分布,该分布取决于一个 n 维向量 $a$ 和一个 n 维约束向量 w(财富份额)。
我想创建一个有 N 个人的 "society",即 N 个人的列表。为此,我创建了两个 n×N 矩阵 A 和 W。我现在循环 1 到 N 来创建个体。
Society <- list()
### doesn't evaluate theta at the time, but does w...
for (i in 1:Npeople) {
w <- WealthDist[i,]
u <- function(x) prod(x^A[i,])
P <- list(u,w)
names(P) <- c("objective","w")
Society[[length(Society)+1]] <- P
}
w gets 是按价值传递的,因此每个人都获得了适量的财富。但是 A 是按引用传递的——每个人都被分配了相同的函数 u(即使用 i = N 的函数)
为了完成它,接下来的步骤是获得协会,并通过两次优化获得 "equilibrium point"。
在 f
a
f <- function(x) {a<-1;x + a}
R 不通过引用传递;一切都按值传递给函数。正如您所注意到的,由于 a
是在全局环境中定义的,因此引用 a
的函数引用的是 a
的全局值,该值可能会发生变化。为确保使用a
的特定值,您可以将其用作函数中的参数。
f <- function(x, a = 1) {
x + a
}
这将a
定义为默认为1的参数。函数使用的a
的值将始终是传递给函数的值,无论a
在全局环境中定义。
如果您要使用 lapply()
,只需将 a
作为参数传递给 lapply()
。
lapply(X, f, a = <value>)
您可以创建一个使用锁定绑定的函数,并创建一个函数来完成您的目的。 a 的前值将用于 w
,它将存储在函数的环境中,并且不会被 a
.
a <- 1
j <- new.env() # create a new environment
create.func <- function () {
j$w <<- a
function (x) {
x+ j$w
}
}
f <- create.func()
a <- 2
f(2)
[1] 3 # if w was changed this should be 4
致谢 Andrew Taylor(见评论)
编辑: 注意:如果你调用 create.func
,f 会改变,即使你没有将它存储到 f 中。为避免这种情况,您可以编写此代码(这显然取决于您想要什么)。
a <- 1
create.func <- function (x) {
j <- new.env()
j$w <- a
function (x) {
x + j$w
}
}
f <- create.func()
f(1)
[1] 2
a <- 2
q <- create.func()
q(1)
[1] 3
f(1)
[1] 2
编辑 2: 延迟求值不适用于此处,因为 a 是通过设置为 j$w
来求值的。如果您将其用作参数,请说:
function(a)
function(x)
#use a here
您必须在定义第二个函数之前使用 force
,因为那样它就不会被计算。
编辑 3: 我删除了 foo <-
等。该函数将在声明后立即 return,因为您希望它相似到您的 link.
由 OP 编辑只是为了添加到已接受的答案中,本着 Function Factory in R 下面的代码有效:
funs.gen <- function(n) {
force(n)
function(x) {
x + n
}
}
funs = list()
for (i in seq(length(names))) {
n = names[i]
funs[[n]] = funs.gen(i)
}