Создание сценария .R внутри функции и передача переменной через (RODBC) - PullRequest
11 голосов
/ 28 июля 2011

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

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

Итак,почему-то он не читает в переменной 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()

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

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

Ответы [ 3 ]

25 голосов
/ 29 июля 2011

Как я уже сказал в своем комментарии, код source 'по умолчанию оценивается в глобальной среде. Установите 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="")
6 голосов
/ 29 июля 2011

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

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, что позволяет указать среду. Окружение может также быть списком, , поэтому, если вам не нужны переменные результата из скрипта, Вы можете просто передать список с нужными параметрами:

sys.source('c:/R/bar.R', list(someparam=42, anotherparam=1:10))
0 голосов
/ 13 июня 2017

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

test <- function() {
 for (i in 1:length(v)) {
  LatestModelRun <<- v[i]
  source("C:/R/foo.r")
  print(unmatched)
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...