在函数内调用源 - 范围问题

时间:2018-01-04 01:59:03

标签: r environment

我正在尝试在函数调用中解决这个范围问题。函数Perform抛出错误。确切地说,错误是Error in eval(expr, envir, enclos) : object 'a' not found。在另一个函数内的函数内调用源是问题(即,对象a不可用于CallScript函数内的Perform函数。 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)

1 个答案:

答案 0 :(得分:1)

我正在玩一些选项并找到解决问题的方法。但我仍然缺乏理解。所以我在这里记录了我对不同场景的发现。希望这有助于人们!

# 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)