【问题标题】:Source-ing an .R script within a function and passing a variable through (RODBC)在函数中获取 .R 脚本并通过 (RODBC) 传递变量
【发布时间】:2011-10-15 09:11:15
【问题描述】:

我在做某事时遇到了一些小问题。假设我有以下简单的例子。让...

v <- c(606:608) ## Some vector of integers

我也写了一个单独的脚本(我们就叫它foo.R),它有类似的东西(使用RODBC 包):

um <- sqlQuery(artemis,paste("select * from port.tdtf_VaR_Unmatched (",LatestModelRun,")",sep=""))

现在假设我要运行以下循环函数:

test <- function() {
 for (i in 1:length(v)) {
  LatestModelRun <- v[i]
  source("C:/R/foo.r")
  print(unmatched)} }

test() ## Run it

当我这样做时,我收到以下错误: Error in paste("\n\tselect * from port.tdtf_VaR_Unmatched (", LatestModelRun, : object 'LatestModelRun' not found

所以,不知何故,它没有读取在 test 函数中定义的 LatestModelRun 变量。

这是traceback()

7: paste("\n\tselect * from port.tdtf_VaR_Unmatched (", LatestModelRun, 
   ")\n\twhere [PortfolioProduct] not in ('REC - Generic','REC - Green-e NY')\n\torder by [PortfolioProduct], [Year]", 
   sep = "")
6: odbcQuery(channel, query, rows_at_time)
5: sqlQuery(artemis, paste("\n\tselect * from port.tdtf_VaR_Unmatched (", 
   LatestModelRun, ")\n\twhere [PortfolioProduct] not in ('REC - Generic','REC - Green-e NY')\n\torder by [PortfolioProduct], [Year]", 
   sep = ""))
4: eval.with.vis(expr, envir, enclos)
3: eval.with.vis(ei, envir)
2: source("C:/R/foo.r")
1: test()

有人知道我做错了什么吗??

非常感谢任何帮助!谢谢!!

【问题讨论】:

  • 我有这个作为答案,但我决定我不太确定,所以我将它作为评论留下。一种简单的解决方案是将foo.r 的内容作为函数而不是脚本来调用。
  • 环境问题?一般来说,我认为@joran 是正确的,你应该把它作为一个函数来调用,这样你就不会滥用全局变量。但是,如果您坚持使用这种方法,请尝试显式的全局分配和评估。
  • 默认情况下,source'd 代码在全局环境中进行评估。尝试设置local=TRUE,它将评估调用环境中的代码。
  • @gsk3 - 是的,?source 似乎默认在全局环境中进行评估,但在 OP 的回溯中,错误可能发生在更改的环境中 (eval.with.vis)。

标签: r


【解决方案1】:

正如我在评论中所说,source'd 代码默认在全局环境中进行评估。设置local=TRUE 来评估调用环境中的代码。

test <- function() {
  for (i in 1:length(v)) {
    LatestModelRun <- v[i]
    source("C:/R/foo.r", local=TRUE)
    print(unmatched)
  }
}
v <- c(606:608)
test()
# [1] "select * from port.tdtf_VaR_Unmatched (606)"
# [1] "select * from port.tdtf_VaR_Unmatched (607)"
# [1] "select * from port.tdtf_VaR_Unmatched (608)"

其中foo.r 包含:

unmatched <-
  paste("select * from port.tdtf_VaR_Unmatched (",LatestModelRun,")",sep="")

【讨论】:

    【解决方案2】:

    约书亚的回答既甜美又简单。我有一个变体,可以让您更明确地向脚本传递参数:

    test <- function() {
      for (i in 1:length(v)) {
        e <- new.env()
        e$LatestModelRun <- v[i]
        sys.source('c:/R/foo.R', e)
        print(e$unmatched)
      }
    }
    

    这个用表弟sourcesys.source 允许您指定环境。 环境实际上也可以是一个列表,所以如果您不需要脚本中的任何结果变量, 你可以简单地传入一个带有你需要的参数的列表:

    sys.source('c:/R/bar.R', list(someparam=42, anotherparam=1:10))
    

    【讨论】:

      【解决方案3】:

      函数中设置的变量不是全局变量,除非由&lt;&lt;- 设置,所以这不可行吗?

      test <- function() {
       for (i in 1:length(v)) {
        LatestModelRun <<- v[i]
        source("C:/R/foo.r")
        print(unmatched)
       }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-07
        • 1970-01-01
        • 2021-07-18
        • 2019-10-16
        • 2019-01-19
        • 2022-11-05
        • 2012-04-20
        • 1970-01-01
        相关资源
        最近更新 更多