2013-03-13 1 views
31

まず、私はknitrと再現性のある解析のコンセプトを非常に熟知していますが、私の現在のワークフロー(Word文書への多くのコピー貼り付けを含む)を改善する可能性を見てください。knitrで複数のpdfレポートを作成するループを使用すると、ちょっとした助けを必要とします

私は多くの場合、グループ(この例では病院)によって複数のレポートを作成しなければならず、各病院内で、結果を報告している多くの異なる病棟が存在することがあります。以前はループを使ってRですべてのプロットと解析を実行した後、コピー/貼り付け作業を開始しました。しかし、この投稿(Can Sweave produce many pdfs automatically?)を読んだ後、私は実際に多くのステップをスキップして、Rnw/knitrを通してRから報告することができるという希望を与えました。

しかし、Rnw内のR環境が私がそれに渡そうとしているループ変数を認識していないように見えることがあります。 )。私のニット()のコードチャンクを実行しようとした後

## make my data 
Hospital <- c(rep("A", 20), rep("B", 20)) 
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2) 
Month <- rep(seq(1:10), 4) 
Outcomes <- rnorm(40, 20, 5) 
df <- data.frame(Hospital, Ward, Month, Outcomes) 


## Here is my current work flow-- produce all plots, but export as png and cut/paste 
for(hosp in unique(df$Hospital)){ 
    subgroup <- df[ df$Hospital == hosp,] 
    for(ward in unique(subgroup$Ward)){ 
    subgroup2 <- subgroup[subgroup$Ward == ward,] 
    savename <- paste(hosp, ward) 
    plot(subgroup2$Month, subgroup2$Outcomes, type="o", main=paste("Trend plot for", savename)) 
    } 
} 
# followed by much copy/pasting 


## Here is what I'm trying to go for using knitr 
library(knitr) 
for (hosp in unique(df$Hospital)){ 
    knit("C:file.path\\testing_loops.Rnw", output=paste('report_', Hospital, '.tex', sep="")) 
} 

## With the following *Rnw file 
## start *.Rnw Code 
\documentclass[10pt]{article} 
\usepackage[margin=1.15 in]{geometry} 
<<loaddata, echo=FALSE, message=FALSE>>= 
    Hospital <- c(rep("A", 20), rep("B", 20)) 
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2) 
Month <- rep(seq(1:10), 4) 
Outcomes <- rnorm(40, 20, 5) 
df <- data.frame(Hospital, Ward, Month, Outcomes) 
subgroup <- df[ df$Hospital == hosp,] 
@ 

\begin{document} 
<<setup, echo=FALSE >>= 
    opts_chunk$set(fig.path = paste("test", hosp , sep="")) 
@ 

Some infomative text about hospital \Sexpr{hosp} 

<<plots, echo=FALSE >>= 
    for(ward in unique(subgroup$Ward)){ 
    subgroup2 <- subgroup[subgroup$Ward == ward,] 
    #  subgroup2 <- subgroup2[ order(subgroup2$Month),] 
    savename <- paste(hosp, ward) 
    plot(subgroup2$Month, subgroup2$Outcomes, type="o", main=paste("Trend plot for", savename)) 
    } 
@ 
\end{document} 


## To be then turned into pdf with this 
tools::texi2pdf("C:file.path\\report_A.tex", clean = TRUE, quiet = TRUE) 

私はこのエラーを取得する:

Error in file(con, "w") : invalid 'description' argument 

そして、私は* .texファイルが作成されたディレクトリに見たとき、私は見ることができます病院Aの2つのpdfプロットが作成されました(Bはありません)。病院固有の* .texファイルはpdfに編成されませんでした。あなたが提供することができる任意のヘルプの事前に感謝!

答えて

15

あなたはhospではなく.Rnwファイル内のデータを再定義し、私は警告があなたがHospitalと一緒に(病院のフルベクトル)を出力名を入れているという事実から来ていると思うする必要はありません(ループインデックス)。

私はより一般的な質問に答えるつもりあなたの例に続き、testingloops.Rnw

\documentclass[10pt]{article} 
\usepackage[margin=1.15 in]{geometry} 
<<loaddata, echo=FALSE, message=FALSE>>= 
subgroup <- df[ df$Hospital == hosp,] 
@ 

\begin{document} 
<<setup, echo=FALSE >>= 
    opts_chunk$set(fig.path = paste("test", hosp , sep="")) 
@ 

Some infomative text about hospital \Sexpr{hosp} 

<<plots, echo=FALSE >>= 
    for(ward in unique(subgroup$Ward)){ 
    subgroup2 <- subgroup[subgroup$Ward == ward,] 
    #  subgroup2 <- subgroup2[ order(subgroup2$Month),] 
    savename <- paste(hosp, ward) 
    plot(subgroup2$Month, subgroup2$Outcomes, type="o", main=paste("Trend plot for", savename)) 
    } 
@ 
\end{document} 

だろうとドライバRファイルは、この答えではちょうど

## make my data 
Hospital <- c(rep("A", 20), rep("B", 20)) 
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2) 
Month <- rep(seq(1:10), 4) 
Outcomes <- rnorm(40, 20, 5) 
df <- data.frame(Hospital, Ward, Month, Outcomes) 

## knitr loop 
library("knitr") 
for (hosp in unique(df$Hospital)){ 
    knit2pdf("testingloops.Rnw", output=paste0('report_', hosp, '.tex')) 
} 
+1

いくつかの行を保存する 'knit2pdf'に+1してください。 – Ben

+0

ブライアン、そして私のマシン(何らかの理由で)は、lapply tools :: texi2pdfよりもknit2pdfをたくさん好きです!驚くばかり! – Chris

+0

@Brian Diggs、これをまだ監視しているかどうかはわかりませんが、各区のプロットの後ろに記述テキスト*を挿入したい場合は.Rnwファイルのプロットコードループ内にあります。一番いい方法?プロット直後にcat( "\\ Sexpr {ward}についての情報テキストです")を挿入しようとしました。また、コードチャンクオプションtidy.opts = list(comment = "")も有効にしていますが、knit2pdfは両方のプロットの後にテキストを配置します。また、コンパイル時に "\"がエスケープエラー(?)を引き起こします。 – Chris

10

大きな質問です!あなたの質問にあなたが提供した他のビットと私のためにこれは動作します。 hospをちょうどxに変更しました。私は、多くの場合、よりR -ishと考えているようだlapplyと無名関数、を使用してループを交換しましたtest.rnw

# input data 
Hospital <- c(rep("A", 20), rep("B", 20)) 
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2) 
Month <- rep(seq(1:10), 4) 
Outcomes <- rnorm(40, 20, 5) 
df <- data.frame(Hospital, Ward, Month, Outcomes) 

# generate the tex files, one for each hospital in df 
library(knitr) 
lapply(unique(df$Hospital), function(x) 
     knit("C:\\emacs\\test.rnw", 
      output=paste('report_', x, '.tex', sep=""))) 

# generate PDFs from the tex files, one for each hospital in df 
lapply(unique(df$Hospital), function(x) 
     tools::texi2pdf(paste0("C:\\emacs\\", paste0('report_', x, '.tex')), 
         clean = TRUE, quiet = TRUE)) 

あなたRnwファイルと呼ばれてきました。

ここで私はrnwファイルにxhospを置き換えどこで見ることができます:結果は2つのTEXファイル(report_A.tex、report_B.tex)、フィギュアのための4つのPDFファイル(A1です

\documentclass[10pt]{article} 
\usepackage[margin=1.15 in]{geometry} 
<<loaddata, echo=FALSE, message=FALSE>>= 
    Hospital <- c(rep("A", 20), rep("B", 20)) 
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2) 
Month <- rep(seq(1:10), 4) 
Outcomes <- rnorm(40, 20, 5) 
df <- data.frame(Hospital, Ward, Month, Outcomes) 
subgroup <- df[ df$Hospital == x,] 
@ 

\begin{document} 
<<setup, echo=FALSE >>= 
    opts_chunk$set(fig.path = paste("test", x , sep="")) 
@ 

Some informative text about hospital \Sexpr{x} 

<<plots, echo=FALSE >>= 
    for(ward in unique(subgroup$Ward)){ 
    subgroup2 <- subgroup[subgroup$Ward == ward,] 
    #  subgroup2 <- subgroup2[ order(subgroup2$Month),] 
    savename <- paste(x, ward) 
    plot(subgroup2$Month, subgroup2$Outcomes, type="o", main=paste("Trend plot for", savename)) 
    } 
@ 
\end{document} 

、A2、B1、B2)とレポート用の2つのPDF(report_A.pdf、report_B.pdf)で構成されています。それはあなたが後になったことですか?

+2

絶対に!私は、ツール(texi2pdf)をループする際に2番目のラップチャンクを動かすのに苦労していますが、私はそれを理解することができます。私の* .texファイルを最初に飾りつけるのは素晴らしいです!とても感謝しています!! – Chris

+1

Brian Diggsの答えのように 'knit2pdf'を試してみましたか? 2番目の 'lapply'を次のように置き換えることができます:' library(knitr); '012:\\ emacs \\ test.rnw'、output = paste0( 'report_'、x、 '.tex'))) ' – Ben

+0

By' replace 「私は二番目の「恋人」を離れています。私を許してください。 – Ben

0

次のようになりますし、ループを使用して を」あなたの具体的な例ではなく、複数のpdfレポートを生成します。これは、この傾向がノブとして続くことが非常に難しいためです。私はそれを最終的に(HTML版)動作させることができたので、これは私の謙虚な解決策です。おそらくもっと良いものがここに掲載されているかもしれませんが、私はそれらをまだ完全に理解することはできません。

  1. デザインとRMDファイルを作成し、作業\入力 ディレクトリに保存します(Rstudioに:ファイル - > newfile-> Rマークダウン)。このファイルには、レポートにプロットを作成するために必要なすべての関数が含まれている必要があります(これらのコードチャンクの1つで宣言してください)。 このファイルは今後のすべてのレポートのテンプレートと考えてください。私は を(2)のそれをカバーする前に、それを噛んだ後にその環境にデータを渡すことについて、 を心配しないでください。理解すべき重要な問題は、すべての計算が であることです(RMD ファイルをレンダリングした時点で)。

  2. 異なる制御ファイルで使用する必要があるループを作成します。私の場合、 がディレクトリ内のすべてのファイルを反復処理し、それらをデータ フレームにするループがあります。私はそれらをプロットするために、 他のデータ変数と共に、RMDにそれらのデータフレームを渡したいと思います。これは、そのを行う方法です:

    run_on_all<-function(path_in="path:\\where\\your\\input\\and\\RMD\\is", path_out="path:\\where\\your\\output\\will\\be") setwd(path_in) ibrary(rmarkdown) library(knitr) list_of_file_names=list.files(path = getwd, pattern = "*.csv") #this gets a list of the input files names for (file_name in list_of_file_names) { data=read.csv(file_name) #read file into data frame report_name=paste(some_variable_name,".html",sep="") render("your_template.Rmd",output_file =report_name,output_dir =path_out,list(data,all other parameters you want to input into the RMD))} }

  3. 最も重要なコマンドがレンダリング関数呼び出しです。それは あなたが望むparamentersをRMD環境に投げることができます。また、レポートの名前を変更して出力先を に変更することもできます。さらに、それを呼び出すことにより、 というレポートも生成されますので、すべてを1行で取得できます(ただし、RMDの呼び出しが関数内にある場合は、入力した変数が欠落していますが、レポートまだ正常に公開されます)

要約

あなたはすべての追加のレポートおよび制御ファイルのテンプレートとなりますRMDファイルを、need- 2つのファイルがあります。制御ファイルはデータを取得し、それを咀嚼し、噛んだパラメータを(レンダリング機能を介して)RMDに渡す。 RMDはデータを取得し、いくつかの計算を行い、プロットし、それを新しいファイルに(また、レンダリング機能によって)パブリッシュします。私が助けてくれることを願っている

関連する問題