在函数内调用源 - 范围问题
Calling source within a function - scoping issue
我试图在函数调用中解决这个范围问题。函数 Perform
抛出错误。准确地说,错误是Error in eval(expr, envir, enclos) : object 'a' not found
。在另一个函数内的函数内调用源是问题所在(即,对象 a
对 Perform
函数内的 CallScript
函数不可用)。 Perforxm1
很好 - 所以我想了解如何修复 Perform
函数。 (Add_a_b.R
文件是一个仅包含 a+b
用于测试目的的脚本)。提前致谢。
CallScript<-function(ii){
source(ii,echo = T,local=T)
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform1<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=T)
}
Perform(a=10,b=15)
Perform1(a=10,b=15)
我尝试了一些选项并找到了解决问题的方法。但我仍然缺乏理解。所以我在这里记录了我对不同场景的发现。希望这对人们有所帮助!
# To call within another function, reference enclosing environment!!
# Fixed my problem.
# Is there any other methods to achieve this?
CallScript<-function(ii){
source(ii,echo = T, local=parent.frame())
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
# Using local=T or local=environment() options don't work in this scenario!
CallScript<-function(ii){
source(ii,echo = T, local=T)
#source(ii,echo = T, local=environment())
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
# I also found out that these also work.
Perform_env<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=environment())
}
Perform_loc<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=T)
}
Perform_env(a=10,b=15)
Perform_loc(a=10,b=15)
# But this doesn't work
Perform_par<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=parent.frame())
}
Perform_par(a=10,b=15)
使事情复杂化的是另一种情况。除了 local=F
,所有三个选项都适用于这种情况。
# CallScript defined within `Perform` function.
Perform<-function(a,b){
CallScript<-function(ii){
# parent.frame works
#source(ii,echo = T,local=parent.frame())
# environment works
#source(ii,echo = T,local=environment())
# Local=T also work
source(ii,echo = T,local=T)
}
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
根据@MrFlick 的建议,这也有效:
CallScript<-function(ii){
a <- get("a", parent.frame())
b <- get("b", parent.frame())
source(ii,echo = T, local=T)
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
我试图在函数调用中解决这个范围问题。函数 Perform
抛出错误。准确地说,错误是Error in eval(expr, envir, enclos) : object 'a' not found
。在另一个函数内的函数内调用源是问题所在(即,对象 a
对 Perform
函数内的 CallScript
函数不可用)。 Perforxm1
很好 - 所以我想了解如何修复 Perform
函数。 (Add_a_b.R
文件是一个仅包含 a+b
用于测试目的的脚本)。提前致谢。
CallScript<-function(ii){
source(ii,echo = T,local=T)
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform1<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=T)
}
Perform(a=10,b=15)
Perform1(a=10,b=15)
我尝试了一些选项并找到了解决问题的方法。但我仍然缺乏理解。所以我在这里记录了我对不同场景的发现。希望这对人们有所帮助!
# To call within another function, reference enclosing environment!!
# Fixed my problem.
# Is there any other methods to achieve this?
CallScript<-function(ii){
source(ii,echo = T, local=parent.frame())
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
# Using local=T or local=environment() options don't work in this scenario!
CallScript<-function(ii){
source(ii,echo = T, local=T)
#source(ii,echo = T, local=environment())
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
# I also found out that these also work.
Perform_env<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=environment())
}
Perform_loc<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=T)
}
Perform_env(a=10,b=15)
Perform_loc(a=10,b=15)
# But this doesn't work
Perform_par<-function(a,b){
ii<-'~/Test/Add_a_b.R'
source(ii,echo = T,local=parent.frame())
}
Perform_par(a=10,b=15)
使事情复杂化的是另一种情况。除了 local=F
,所有三个选项都适用于这种情况。
# CallScript defined within `Perform` function.
Perform<-function(a,b){
CallScript<-function(ii){
# parent.frame works
#source(ii,echo = T,local=parent.frame())
# environment works
#source(ii,echo = T,local=environment())
# Local=T also work
source(ii,echo = T,local=T)
}
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)
根据@MrFlick 的建议,这也有效:
CallScript<-function(ii){
a <- get("a", parent.frame())
b <- get("b", parent.frame())
source(ii,echo = T, local=T)
}
Perform<-function(a,b){
ii<-'~/Test/Add_a_b.R'
CallScript(ii)
}
Perform(a=10,b=15)