2015-11-05 115 views
2

我有以下兩個功能:傳遞變量

f1<-function(){ 
txt<-1234 
f2(where="txt") 
} 

f2<-function(where){ 
foo<-eval(parse(text = where))*2 
return(foo) 
} 

調用當f1(),我希望它返回2468然而

> f1() 
Error in eval(expr, envir, enclos) : object 'txt' not found 

我不明白爲什麼,特別是爲什麼f2不知道txt。當然,它沒有在自己的環境中定義,但是它是在調用者環境中定義的(在f1中),我認爲在f1中定義的所有內容都應該對f2可見?

當然,如果在F1我有

txt<<-1234 

然後

> f1() 
[1] 2468 

但我寧願避免全球分配(在實際的代碼,我不希望有流浪全局對象.. )

所以問題是,我如何讓fxt(在f1中定義)對f2可見?

感謝

(並且如果你不知道,現實生活中的F2比較複雜,使得傳遞變量的名稱是有道理的;在​​任何情況下,它是由其他人創作的功能上,我無法控制,所以解決方案應該來自f1方)。

回答

2

1)問題是真正與f2,沒有,所以f2應該是固定的。通常會定義f2以明確地傳遞環境。使用此代碼f1將按原樣工作。

f2 <- function(where, envir = parent.frame()) { 
    eval(parse(text = where), envir = envir)*2` . 
} 

2)以下是較不理想;

f1 <- function() { 
    txt <- 1234 
    environment(f2) <- environment() 
    f2(where = "txt") 
} 

3)第三個選項是F1中定義F2:但是,如果我們沒有控制權f2那麼我們就可以在f1(現在在哪裏f2是持平的問題)做到這一點

f1 <- function(){ 
    f2 <- function(where) eval(parse(text = where))*2 
    txt <- 1234 
    f2(where = "txt") 
} 
f1() 
+0

非常好,謝謝! – jfmoyen

+0

增加了第三個選項 –

2

f1指定envir論點evalparent.frame()

f2<-function(where){ 
    foo<-eval(parse(text = where), envir= parent.frame())*2 
    return(foo) 
} 

f1() 
#[1] 2468 
+0

它確實有效。但是在f1方面有沒有解決方案(請參閱我原來的問題中的最後一句話,我沒有在實際代碼中控制f2)?另外 - 爲什麼?我認爲默認行爲是查看所有上游環境(從本地,到調用環境,到全球...)? – jfmoyen

+0

此外 - eval()的幫助文件變爲「用法:eval(expr,envir = parent.frame()....」,所以parent.frame()應該是默認的,並且應該沒有必要明確指定它? – jfmoyen