20

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 [PortfolioProduct], [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!!

4
  • I had this as an answer, but I decided I wasn't too sure about it, so I'll leave it as a comment instead. One simplistic solution would be to call the contents of foo.r as a function, rather than a script. Commented Jul 28, 2011 at 18:52
  • Environment issue? In general I think @joran is right and you should call this as a function so you don't abuse globals. But if you're stuck with this approach, try explicit global assignment and evaluation. Commented Jul 28, 2011 at 18:55
  • 1
    By default the source'd code is evaluated in the global environment. Try setting local=TRUE, which will evaluate the code in the calling environment. Commented Jul 28, 2011 at 19:01
  • @gsk3 - Yeah, it appears ?source defaults to evaluating in the global environment, but in the OP's traceback it appears the error may occur inside an altered environment (eval.with.vis). Commented Jul 28, 2011 at 19:02

4 Answers 4

41

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="")
Sign up to request clarification or add additional context in comments.

Comments

10

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

Comments

-1

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

Comments

-1

I have a good idea. It is not needed to write the path of the "foo.r" function as: "C:/R/foo.r" You can if it is within your package, write it as: "source("~/mat.r", local=TRUE)".

Best . Ali

2 Comments

This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
They weren't asking about file paths, and they don't seem to be working on a package. If they were working on a package, sourcing other scripts would be an anti-pattern

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.