我有一个将矢量设置为字符串的函数,使用新名称复制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向量?
由于
保罗。
答案 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; - 运算符将变量放在全局环境中。 (我想)。
其他人想评论谁更了解环境?