I can't seem to make apply function access/modify a variable that is declared outside... what gives?
我似乎无法使apply函数访问/修改一个在…到底发生了什么事?
x = data.frame(age=c(11,12,13), weight=c(100,105,110))
x
testme <- function(df) {
i <- 0
apply(df, 1, function(x) {
age <- x[1]
weight <- x[2]
cat(sprintf("age=%d, weight=%d\n", age, weight))
i <- i+1 #this could not access the i variable in outer scope
z <- z+1 #this could not access the global variable
})
cat(sprintf("i=%d\n", i))
i
}
z <- 0
y <- testme(x)
cat(sprintf("y=%d, z=%d\n", y, z))
Results:
结果:
age=11, weight=100
age=12, weight=105
age=13, weight=110
i=0
y=0, z=0
2 个解决方案
#1
34
Using the <<-
operator you can write to variables in outer scopes:
使用<-运算符可以在外部作用域中对变量进行写入:
x = data.frame(age=c(11,12,13), weight=c(100,105,110))
x
testme <- function(df) {
i <- 0
apply(df, 1, function(x) {
age <- x[1]
weight <- x[2]
cat(sprintf("age=%d, weight=%d\n", age, weight))
i <<- i+1 #this could not access the i variable in outer scope
z <<- z+1 #this could not access the global variable
})
cat(sprintf("i=%d\n", i))
i
}
z <- 0
y <- testme(x)
cat(sprintf("y=%d, z=%d\n", y, z))
The result here:
结果:
age=11, weight=100
age=12, weight=105
age=13, weight=110
i=3
y=3, z=3
Note that the usage of <<-
is dangerous, as you break up scoping. Do this only if really necessary and if you do, document that behavior clearly (at least in bigger scripts)
注意,使用<< <-是危险的,因为您要分解范围。只有在必要的时候才这样做,如果这样做了,就应该清楚地记录这种行为(至少在更大的脚本中)
#2
7
try the following inside your apply. Experiment with the value of n. I believe that for i
it should be one less than for z
.
在你的申请中试试下面的方法。实验n的值,我认为I应该比z小1。
assign("i", i+1, envir=parent.frame(n=2))
assign("z", z+1, envir=parent.frame(n=3))
testme <- function(df) {
i <- 0
apply(df, 1, function(x) {
age <- x[1]
weight <- x[2]
cat(sprintf("age=%d, weight=%d\n", age, weight))
## ADDED THESE LINES
assign("i", i+1, envir=parent.frame(2))
assign("z", z+1, envir=parent.frame(3))
})
cat(sprintf("i=%d\n", i))
i
}
OUTPUT
> z <- 0
> y <- testme(x)
age=11, weight=100
age=12, weight=105
age=13, weight=110
i=3
> cat(sprintf("y=%d, z=%d\n", y, z))
y=3, z=3
#1
34
Using the <<-
operator you can write to variables in outer scopes:
使用<-运算符可以在外部作用域中对变量进行写入:
x = data.frame(age=c(11,12,13), weight=c(100,105,110))
x
testme <- function(df) {
i <- 0
apply(df, 1, function(x) {
age <- x[1]
weight <- x[2]
cat(sprintf("age=%d, weight=%d\n", age, weight))
i <<- i+1 #this could not access the i variable in outer scope
z <<- z+1 #this could not access the global variable
})
cat(sprintf("i=%d\n", i))
i
}
z <- 0
y <- testme(x)
cat(sprintf("y=%d, z=%d\n", y, z))
The result here:
结果:
age=11, weight=100
age=12, weight=105
age=13, weight=110
i=3
y=3, z=3
Note that the usage of <<-
is dangerous, as you break up scoping. Do this only if really necessary and if you do, document that behavior clearly (at least in bigger scripts)
注意,使用<< <-是危险的,因为您要分解范围。只有在必要的时候才这样做,如果这样做了,就应该清楚地记录这种行为(至少在更大的脚本中)
#2
7
try the following inside your apply. Experiment with the value of n. I believe that for i
it should be one less than for z
.
在你的申请中试试下面的方法。实验n的值,我认为I应该比z小1。
assign("i", i+1, envir=parent.frame(n=2))
assign("z", z+1, envir=parent.frame(n=3))
testme <- function(df) {
i <- 0
apply(df, 1, function(x) {
age <- x[1]
weight <- x[2]
cat(sprintf("age=%d, weight=%d\n", age, weight))
## ADDED THESE LINES
assign("i", i+1, envir=parent.frame(2))
assign("z", z+1, envir=parent.frame(3))
})
cat(sprintf("i=%d\n", i))
i
}
OUTPUT
> z <- 0
> y <- testme(x)
age=11, weight=100
age=12, weight=105
age=13, weight=110
i=3
> cat(sprintf("y=%d, z=%d\n", y, z))
y=3, z=3