如果从函数运行,Sweave无法看到向量?

时间:2010-05-26 11:03:37

标签: r sweave

我有一个将矢量设置为字符串的函数,使用新名称复制Sweave文档然后运行该Sweave。在Sweave文档中我想使用我在函数中设置的向量,但它似乎没有看到它。

(编辑:我改变了这个功能,使用了Dirk建议的tempdir(())

我创建了一个sweave文件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}

我有这个功能;

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

如果我直接从函数运行代码,则生成的文件具有ls();

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

但是如果我调用onOK(),我会得到这个输出;

> ls()
[1] "onOK"

并且print(... chstud ...))函数会生成错误。

我怀疑这是一个环境问题,但我假设因为对Sweave的调用发生在onOK函数中,它将在同一个环境中,并且会看到函数内创建的所有对象。如何让Sweave过程看到chstud向量?

由于

保罗。

2 个答案:

答案 0 :(得分:2)

我有类似的问题。最终我找到了一个“适合我”的解决方法,虽然它可能不是解决这个问题最优雅的方法。

在我的函数中,在执行'Sweave'之前,我将一个语句全局存储在本地环境中:

temp <<- environment()

使用您的代码示例,它看起来像:

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

rm(foo) testFoo()

然后在LaTeX文件中,在第一个块的开头'Sweaved'我恢复了必要的变量,但你也可以使用'temp $ foo'来访问在函数中创建的'foo'变量。这样我就可以避免全局存储多个变量。

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

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

\maketitle

<<>>=

if(exists("foo", envir=temp)) { print(temp$foo) }
ls()
Sys.time()
@ 
\end{document}

就像我上面写的那样 - 这很有效,但不是很优雅。

答案 1 :(得分:0)

好的,我意识到我对“简单,自包含的例子”的初步想法并不是特别简单或有用。所以我重新编写了我的例子并为自己得到了一个答案,虽然我喜欢有人为了解释原因,甚至提出更好的解决方案, 这是我的示例test_sweave.Rnw文件

% 
\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}

如果我运行此代码;

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

rm(foo) testFoo()

我的结果文件不包含字符串foo的内容。

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

如果我运行此代码(即,同样的事情,只需直接运行)

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

我的结果文件确实包含foo字符串

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

如果我运行此代码

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

rm(foo)
testBar()

我的结果文件还包含foo字符串

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

因此,似乎sweave在全球环境中运行,而不是在它被调用的环境中运行。这意味着在从函数运行sweave时将变量传递给sweave的唯一方法是使用&lt;&lt; - 运算符将变量放在全局环境中。 (我想)。

其他人想评论谁更了解环境?