[R] how to modify variables of another frame (but not global)

Gabor Grothendieck ggrothendieck at myway.com
Tue Mar 23 15:12:21 CET 2004


There are three ways I know of.  Actually there are some QUESTIONS I
have related to all this which I have interspersed.

The first, f1, uses assign/get and is shown in f1 below.  Note that we had to
copy all of z even though we only changed one element.  You can't do this:
   assign("z[1]",...) # wrong

The second, f2, uses <<- which searches through its parent environments for the
assigned-to variable.  As can be seen in f2a near the end it appears to do the
same thing as assign underneath as the entire z in f seems to have been copied
over.  Note that the right hand side of the assignment is still handled
normally.  QUESTION: Could someone explain what is going on in f2a in detail???

The third, f3 uses eval.parent.  It looks similar to <<- but its actually
different.  eval.parent evaluates the expression in the parent environment of f
so it never looks within f.  Both sides of the assignment are handled in the
parent environment in this one. This can be seen in f3a where the z defined in
f is completely ignored.  I believe that eval.parent does modify individual
cells without copying the entire structure.  QUESTION:  Is that right ???

> # 1. assign and get
> 
> f1 <- function() {
+    f <- function(x,k) { 
+       xc <- as.character(substitute(x))   # character representation of name
+       x <- get( xc, parent.frame() )
+       x[1] <- x[1] + k
+       assign( xc, x, parent.frame() )
+    }
+    z <- 1:5
+    f(z,1)
+    print(z)
+ }
> z <- 7
> f1()
[1] 2 2 3 4 5
> z
[1] 7


> # 2. <<-
> 
> f2 <- function() {
+    f <- function(x,k) eval(eval(substitute( x[1] <<- x[1] + k )))
+    z <- 1:5
+    f(z,1)
+    print(z)
+ }
> z <- 7
> f2()
[1] 2 2 3 4 5
> z
[1] 7
> 
> # 3. eval.parent
> 
> f3 <- function() {
+    f <- function(x,k) eval(eval.parent(substitute(x[1] <- x[1] + k )))
+    z <- 1:5
+    f(z,1)
+    print(z)
+ }
> z <- 7
> f3()
[1] 2 2 3 4 5
> z
[1] 7


> # <<- with a local z
> 
> f2a <- function() {
+    f <- function(x,k) {
+       z <- 10:12
+       eval(eval(substitute( x[1] <<- x[1] + k )))
+    }
+    z <- 1:5
+    f(z,1)
+    print(z)
+ }
> z <- 7
> f2a()
[1] 11 11 12
> z
[1] 7


> # eval parent with a local z
> 
> f3a <- function() {
+    f <- function(x,k) {
+       z <- 10:12
+       eval(eval.parent(substitute(x[1] <- x[1] + k )))
+    }
+    z <- 1:5
+    f(z,1)
+    print(z)
+ }
> z <- 7
> f3a()
[1] 2 2 3 4 5
> z
[1] 7
> 

> R.version.string
[1] "R version 1.8.1, 2003-11-21"

------------------------------------------------------

Here is a copy of just the input 



# 1. assign and get

f1 <- function() {
   f <- function(x,k) { 
      xc <- as.character(substitute(x))   # character representation of name
      x <- get( xc, parent.frame() )
      x[1] <- x[1] + k
      assign( xc, x, parent.frame() )
   }
   z <- 1:5
   f(z,1)
   print(z)
}
z <- 7
f1()
z

# 2. <<-

f2 <- function() {
   f <- function(x,k) eval(eval(substitute( x[1] <<- x[1] + k )))
   z <- 1:5
   f(z,1)
   print(z)
}
z <- 7
f2()
z

# 3. eval.parent

f3 <- function() {
   f <- function(x,k) eval(eval.parent(substitute(x[1] <- x[1] + k )))
   z <- 1:5
   f(z,1)
   print(z)
}
z <- 7
f3()
z

# <<- with a local z

f2a <- function() {
   f <- function(x,k) {
      z <- 10:12
      eval(eval(substitute( x[1] <<- x[1] + k )))
   }
   z <- 1:5
   f(z,1)
   print(z)
}
z <- 7
f2a()
z

# eval parent with a local z

f3a <- function() {
   f <- function(x,k) {
      z <- 10:12
      eval(eval.parent(substitute(x[1] <- x[1] + k )))
   }
   z <- 1:5
   f(z,1)
   print(z)
}
z <- 7
f3a()
z

R.version.string

---

Date:   Tue, 23 Mar 2004 12:17:39 +0100 
From:   Meinhard Ploner <meinhardploner at gmx.net>
To:   <r-help at stat.math.ethz.ch> 
Subject:   [R] how to modify variables of another frame (but not global) 

 
Hello!

Maybe "frame" is not the right term in this context.
I explain my problem by example code:

fun2 <- function(objName, add) {
     ## the object "objName" should be increased by "add",
     ## but the evaluation should be done in the calling function (here: 
fun1)
     ## ...... what's the right code??
}

fun1 <- function() {
     x <- 1

     fun2("x", 10)          ## should modify "x"

     ## now x should be 11, but only here and NOT globally!
     ...
}


I would like to appreciate any solution!
Thanks in advance

Meinhard Ploner




More information about the R-help mailing list