我目前正在处理R中的一个问题,我正在尝试使用定义函数时全局值的值在TabControl
循环中定义函数。但是,每次尝试似乎都有一些问题。
尝试1: 第一次尝试是基本的。
for
这给出了结果
models = list()
nodes = list(c(1), c(2))
d = data.frame(CD=c(1,2))
for (i in 1:2) {
models[[i]] = list()
models[[i]]$outcome = function(dat) {dat$CD %in% nodes[[i]]}
cat(sprintf('\nIteration %d\n', i))
cat(sprintf('\tModel %d outcome\n', i))
print(models[[i]]$outcome(d))
cat(sprintf('\tModel 1 outcome\n'))
print(models[[1]]$outcome(d))
}
cat('\nFinal model 1 outcome')
print(models[[1]]$outcome(d))
cat('\nFinal model 2 outcome')
print(models[[2]]$outcome(d))
函数Iteration 1
Model 1 outcome
[1] TRUE FALSE
Model 1 outcome
[1] TRUE FALSE
Iteration 2
Model 2 outcome
[1] FALSE TRUE
Model 1 outcome
[1] FALSE TRUE
Final model 1 outcome
[1] FALSE TRUE
Final model 2 outcome
[1] FALSE TRUE
已经从第一次迭代修改为第二次迭代,因为它依赖于已更改的models[[1]]$outcome
,足够公平。
尝试2:
第二次尝试是在nodes[[i]]
中使用部分函数。
pryr
这给出了相同的结果
library(pryr)
f = function(dat, x) {dat$CD %in% x}
models = list()
nodes = list(c(1), c(2))
d = data.frame(CD=c(1,2))
for (i in 1:2) {
models[[i]] = list()
models[[i]]$outcome = partial(f, x=nodes[[i]])
cat(sprintf('\nIteration %d\n', i))
cat(sprintf('\tModel %d outcome\n', i))
print(models[[i]]$outcome(d))
cat(sprintf('\tModel 1 outcome\n'))
print(models[[1]]$outcome(d))
}
cat('\nFinal model 1 outcome')
print(models[[1]]$outcome(d))
cat('\nFinal model 2 outcome')
print(models[[2]]$outcome(d))
这对我来说似乎违反直觉。我希望部分函数在定义函数时复制输入的值。
尝试3:我现在尝试使用函数闭包。
Iteration 1
Model 1 outcome
[1] TRUE FALSE
Model 1 outcome
[1] TRUE FALSE
Iteration 2
Model 2 outcome
[1] FALSE TRUE
Model 1 outcome
[1] FALSE TRUE
Final model 1 outcome
[1] FALSE TRUE
Final model 2 outcome
[1] FALSE TRUE
这给出了结果
f = function(x) {
g = function(dat) {dat$CD %in% x}
}
models = list()
nodes = list(c(1), c(2))
d = data.frame(CD=c(1,2))
for (i in 1:2) {
models[[i]] = list()
models[[i]]$outcome = f(nodes[[i]])
cat(sprintf('\nIteration %d\n', i))
cat(sprintf('\tModel %d outcome\n', i))
print(models[[i]]$outcome(d))
cat(sprintf('\tModel 1 outcome\n'))
print(models[[1]]$outcome(d))
}
cat('\nFinal model 1 outcome')
print(models[[1]]$outcome(d))
cat('\nFinal model 2 outcome')
print(models[[2]]$outcome(d))
好像我们终于到了某个地方。但是有两个问题。首先,如果我们在for循环中注释print语句,就会发生奇怪的事情。
Iteration 1
Model 1 outcome
[1] TRUE FALSE
Model 1 outcome
[1] TRUE FALSE
Iteration 2
Model 2 outcome
[1] FALSE TRUE
Model 1 outcome
[1] TRUE FALSE
Final model 1 outcome
[1] TRUE FALSE
Final model 2 outcome
[1] FALSE TRUE
我们得到了结果
f = function(x) {
g = function(dat) {dat$CD %in% x}
}
models = list()
nodes = list(c(1), c(2))
d = data.frame(CD=c(1,2))
for (i in 1:2) {
models[[i]] = list()
models[[i]]$outcome = f(nodes[[i]])
#cat(sprintf('\nIteration %d\n', i))
#cat(sprintf('\tModel %d outcome\n', i))
#print(models[[i]]$outcome(d))
#cat(sprintf('\tModel 1 outcome\n'))
#print(models[[1]]$outcome(d))
}
cat('\nFinal model 1 outcome')
print(models[[1]]$outcome(d))
cat('\nFinal model 2 outcome')
print(models[[2]]$outcome(d))
因此,印刷品似乎导致我们在print语句时复制全局变量(这是我间接想要的)。但是,更烦人的是,我在函数内运行它并返回Final model 1 outcome
[1] FALSE TRUE
Final model 2 outcome
[1] FALSE TRUE
对象。通过这样做,models
捕获了它所定义的整个环境,这意味着它最终会占用(不必要地)大量内存。
问题
实现我想要做的事情的正确方法是什么,即在函数定义时复制全局变量,而不是指向'在没有捕获整个环境的情况下,我已经定义了我的功能。