1

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

(编辑:我将此函数更改为使用 Dirk 建议的 tempdir(() )

我创建了一个编织文件 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 向量?

谢谢

保罗。

4

2 回答 2

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 文件中,我恢复了必要的变量,但您也可以使用“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}

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

于 2011-01-24T20:57:58.747 回答
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 的唯一方法是使用 <<- 运算符将变量放入全局环境中。(我认为)。

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

于 2010-05-28T09:00:37.523 回答