1

ベクトルを文字列に設定し、新しい名前で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ベクトルを確認するにはどうすればよいですか?

ありがとう

ポール。

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

次に、最初のチャンクの先頭で「Sweaved」になる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

OK、「シンプルで自己完結型の例」という私の最初のアイデアは、特にシンプルでも有用でもなかったことに気づきました。だから私は自分の例をやり直して、自分自身のためにある種の答えを得ましたが、誰かに理由を説明し、より良い解決策を提案してもらいたいのですが、これが私の例の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 に答える