在函数定义时将全局变量复制到局部变量

时间:2017-05-25 09:44:37

标签: r global-variables

我目前正在处理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捕获了它所定义的整个环境,这意味着它最终会占用(不必要地)大量内存。

问题

实现我想要做的事情的正确方法是什么,即在函数定义时复制全局变量,而不是指向'在没有捕获整个环境的情况下,我已经定义了我的功能。

0 个答案:

没有答案