2010-08-09 56 views
2

的d函数在R中,我想调用应用于巨大的data.frame,并将值写回到其他数据框的特定位置。在apply()中分配变量 - 使用<< -

但是,使用'< < - '仅适用于从全局环境调用apply函数的情况。据我所知,'< < - '搜索变量的parent.env()。为什么在bar()而不是bar的环境中调用该函数的父级环境? 谢谢!

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 
+0

请注意,在第一次运行时,bar()没有找到foo。尝试在rm(foo)之后运行它。这意味着它不是在函数内搜索。为什么? – 2010-08-09 12:53:29

+0

感谢您的注意,这是我犯的一个错误,并将其更改为具有两个不同的变量名称。 找不到变量的原因是bar-called函数的parent.env()不是bar的环境。但我也不知道为什么会这样。 – 2010-08-09 13:05:36

+0

这非常违背R编程的精神。通常情况下最好避免使用非局部副作用的功能。 – hadley 2010-08-13 03:09:17

回答

2

由于我在包名称空间内,我必须使用与Etiennebr不同的解决方案。我认为它很优雅:将bar的环境分配给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() 
+0

给出你的constaints,这是一个不错的解决方案。但是,我会认为这些环境就像被称为的俄罗斯套娃娃一样。 << - 似乎不是这种情况。这超出了我的理解。 – 2010-08-09 14:44:20

1

看来R不是在函数内部搜索(我不明白为什么),所以你需要将值赋给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 
+0

谢谢,这解决了这个问题。不幸的是,这只会导致下一个问题: .local(filename,type,...)中的错误: 无法更改'spectrumTitles'的锁定绑定值 (它是变量我想分配给的频谱标题)。 我正在开发一个软件包,并且在软件包内可能无法使用<< - 。 – 2010-08-09 13:18:29

+0

也许你可以看看使用类似 assign(“foo”,foo,loadNamespace(“YourPackage”)) – 2010-08-10 12:55:41

相关问题