tags:

views:

62

answers:

1

I have a function that sets a vector to a string, copies a Sweave document with a new name and then runs that Sweave. Inside the Sweave document I want to use the vector I set in the function, but it doesn't seem to see it.

(Edit: I changed this function to use tempdir(() as suggested by Dirk)

I created a sweave file test_sweave.rnw;

% 
\documentclass[a4paper]{article}
\usepackage[OT1]{fontenc}
\usepackage{Sweave}
\begin{document}

\title{Test Sweave Document}
\author{gb02413}

\maketitle

<<>>=
ls()
Sys.time()
print(paste("The chosen study was ",chstud,sep=""))
@ 
\end{document}

and I have this function;

onOK <- function(){ 
    chstud<-"test" 
    message(paste("Chosen Study is ",chstud,sep="")) 
    newfile<-paste(chstud,"_report",sep="") 
    mypath<-paste(tempdir(),"\\",sep="")
    setwd(mypath) 
    message(paste("Copying test_sweave.Rnw to ",paste(mypath,newfile,".Rnw",sep=""),sep=""))
    file.copy("c:\\local\\test_sweave.Rnw", 
            paste(mypath,newfile,".Rnw",sep=""), overwrite=TRUE) 
    Sweave(paste(mypath,newfile,".Rnw",sep="")) 
    require(tools) 
    texi2dvi(file = paste(mypath,newfile,".tex",sep=""), pdf = TRUE) 
} 

If I run the code from the function directly, the resulting file has this output for ls();

> ls()
[1] "chstud" "mypath" "newfile" "onOK"

However If I call onOK() I get this output;

> ls()
[1] "onOK"

and the print(...chstud...)) function generates an error.

I suspect this is an environment problem, but I assumed because the call to Sweave occurs within the onOK function, it would be in the same enviroment, and would see all the objects created within the function. How can I get the Sweave process to see the chstud vector ?

Thanks

Paul.

A: 

OK, I realise that my initial ideas of a 'simple, self contained example' wasn't particularly simple or usefull. So I redid my example and got a sort of answer for myself, although I'd love someone to exaplain why and even suggest a better solution, Here's my example test_sweave.Rnw file

% 
\documentclass[a4paper]{article}
\usepackage[OT1]{fontenc}
\usepackage{Sweave}
\begin{document}

\title{Test Sweave Document}
\author{Paul Hurley}

\maketitle

<<>>=

if(exists("foo")){print(foo)}
ls()
Sys.time()
@ 
\end{document}

If I run this code;

testFoo<-function(){    
  foo<-"My Test String"     
  Sweave("test_sweave.Rnw")     
  require(tools)    
  texi2dvi(file = "test_sweave.tex", pdf = TRUE) 
}

rm(foo) testFoo()

my resulting file does NOT contain the contents of the string foo.

> if (exists("foo")) {
+ print(foo)
+ }
> ls()
[1] "testFoo"

If I run this code (i.e, the same thing, just run directly)

rm(foo)
foo<-"My Test String"
Sweave("test_sweave.Rnw")
require(tools) 
texi2dvi(file = "test_sweave.tex", pdf = TRUE)

my resulting file does contain the foo string

> if (exists("foo")) {
+ print(foo)
+ }
[1] "My Test String"
> ls()
[1] "foo" "testFoo"

and if I run this code

testBar<-function(){
    foo<<-"My Test String"
    Sweave("test_sweave.Rnw")
    require(tools) 
    texi2dvi(file = "test_sweave.tex", pdf = TRUE)
}

rm(foo)
testBar()

My resulting file also contains the foo string

> if (exists("foo")) {
+ print(foo)
+ }
[1] "My Test String"
> ls()
[1] "foo" "testBar" "testFoo"

So, it seems that sweave runs in the global environment, not in the environment it was called from. This means the only way to pass variables to sweave when sweave is run from a function is to use the <<- operator to put the variable in the global environment. (I think).

Anyone else want to comment who knows more about environments ?

PaulHurleyuk