Исходный .R script внутри функции и передача переменной через (RODBC)

В чем-то, над чем я работаю, я столкнулся с икотой. Предположим, что у меня следующий простой пример. Пусть...

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

У меня также есть отдельный script (просто назовите его 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

Итак, как-то он не читает в переменной LatestModelRun, определенной в функции test.

Здесь 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()

У кого-нибудь есть идея относительно того, что я делаю неправильно?

Любая помощь очень ценится!! Спасибо!!

Ответ 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

Ответ на Джошуа сладок и прост. У меня есть вариант, который позволяет вам более четко описывать, как передавать параметры в script:

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

Это использует двоюродного брата в source; sys.source, который позволяет указать среду. Среда также может быть списком, , поэтому, если вам не нужны переменные результата из script, вы можете просто передать список с необходимыми параметрами:

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

Ответ 3

Переменные, установленные в функции, не являются глобальными, если не заданы <<-, так не будет ли это работать?

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