tags:

views:

45

answers:

2

In R, I want to call apply on a huge data.frame, and write values back into specific positions of other dataframes.

However, using '<<-' only works when I call the apply function from the global environment. As I understand, '<<-' searches the parent.env() for the variable. Why is the parent environment of the function called in bar() not bar's environment? Thanks!

do_write_foo1 <- function(x) {
    cat("parent environment of function called in bar():  ")
    print(parent.env(environment()))
    foo1[x['a']] <<- 100+x['a']
}
do_write_foo2 <- function(x) {
    foo2[x['a']] <<- 100+x['a']
}

bar <- function() {
    cat("bar environment:  ")
    print(environment())
    foo1 <- 1:10
    apply(data.frame(a=1:10),1,do_write_foo1)
    foo1
}

# this does not work:    
bar()
# bar environment:  <environment: 0x3bb6278>
# parent environment of function called in bar():  <environment: R_GlobalEnv>
# Error in foo1[x["a"]] <<- 100 + x["a"] : object 'foo1' not found


# this works:
foo2<-1:10
apply(data.frame(a=1:10),1,do_write_foo2)
foo2
#  [1] 101 102 103 104 105 106 107 108 109 110
+1  A: 

It seems R is not searching inside the function (I don't understand why), so you need to assign the value to the global.env foo.

bar <- function() {
    foo <<-1:10
    apply(data.frame(a=1:10),1,do_write_foo)
    foo
}
bar()
# [1] 101 102 103 104 105 106 107 108 109 110
Etiennebr
Thanks, that solves that question. For my problem at hand, unfortunately, it only leads to a next problem:Error in .local(filename, type, ...) : cannot change value of locked binding for 'spectrumTitles'(It is the variable spectrumTitles I want to assign to).I am developing a package, and inside a package it might not be possible to use <<-.
Maybe you could look at using something like assign("foo", foo, loadNamespace("YourPackage"))
Etiennebr
+2  A: 

As I am inside a package namespace, I have to use a solution different to Etiennebr's. And I think it is rather elegant: Assigning the environment of bar to do_write_foo1.

do_write_foo1 <- function(x) {
    cat("parent environment of function called in bar():  ")
    print(parent.env(environment()))
    foo1[x['a']] <<- 100+x['a']
}

bar <- function() {
    cat("bar environment:  ")
    print(environment())
    foo1 <- 1:10
     environment(do_write_foo1) <- environment()
    apply(data.frame(a=1:10),1,do_write_foo1)
    foo1
}

# now it works:    
bar()
Given your constaints, it is a nice solution. However, I would think the environments are like matryoshka dolls going one in the other as they are called. It seems it is not the case with <<-. It goes beyond my understanding.
Etiennebr