Source-ing an .R script within a function and passing a variable through (RODBC)
I have encountered a bit of a hiccup in something I'm working on. Suppose I have the following simple example. Let...
v <- c(606:608) ## Some vector of integers
I also, have a separate script written (let's just call it foo.R
) which has something like (uses the RODBC
package):
um <- sqlQuery(artemis,paste("select * from port.tdtf_VaR_Unmatched (",LatestModelRun,")",sep=""))
Now suppose I want to run the following loop function:
test <- function() {
for (i in 1:length(v)) {
LatestModelRun <- v[i]
source("C:/R/foo.r")
print(unmatched)} }
test() ## Run it
When I do this, I get the following error:
Error in paste("\n\tselect * from port.tdtf_VaR_Unmatched (", LatestModelRun, :
object 'LatestModelRun' not found
So, somehow it's not reading in the LatestModelRun
variable defined within the test
function.
Here's the 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 [Portfoli开发者_运维百科oProduct], [Year]",
sep = ""))
4: eval.with.vis(expr, envir, enclos)
3: eval.with.vis(ei, envir)
2: source("C:/R/foo.r")
1: test()
Anybody have an idea as to what I'm doing wrong??
Any help is much appreciated!! Thanks!!
As I said in my comment, the source
'd code is evaluated in the global environment by default. Set local=TRUE
to evaluate the code in the calling environment.
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)"
where foo.r
contains:
unmatched <-
paste("select * from port.tdtf_VaR_Unmatched (",LatestModelRun,")",sep="")
Joshua's answer is sweet & simple. I have a variant that allows you to be more explicit in how you pass parameters to the 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)
}
}
This uses the cousin to source
; sys.source
that allows you specify the environment.
The environment can actually also be a list, so if you don't need any result variables from the script,
you can simply passing in a list with the parameters you need:
sys.source('c:/R/bar.R', list(someparam=42, anotherparam=1:10))
Variables set in a function are not global, unless set by <<-
, so wouldn't this work?
test <- function() {
for (i in 1:length(v)) {
LatestModelRun <<- v[i]
source("C:/R/foo.r")
print(unmatched)
}
}
精彩评论