使い方 - rチャンク




複数のpdfレポートを生成するためにループをknitrで使用する... (2)

まず第一に、私はknitrと再現性のある分析のコンセプトにはまだまだ慣れていないことを認めなければなりませんが、現在のワークフロー(Word文書に多くのコピーを貼り付ける)を改善する可能性があります。

私はしばしばグループ(この例では病院)によって複数のレポートを作成しなければならず、各病院内には、結果を報告している多くの異なる病棟があるかもしれません。 以前はループを使ってRですべてのプロットと解析を実行した後、コピー/貼り付け作業を開始しました。 しかし、この記事を読んだ後( Sweaveは多くのPDFを自動的に生成することができますか? )、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)

私のknit()コードチャンクを実行しようとした後、私はこのエラーが発生します:

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

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


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

あなたの例に続いて、 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'))
}

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

  1. デザインでRMDファイルを作成し、それをworking \ inputディレクトリ(Rstudio:file-> 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. 最も重要なコマンドはレンダリング関数呼び出しです。 それはあなたが望むすべてのパラメタをRMD環境に投げることを可能にします。 また、レポートの名前を変更したり、出力場所を変更したりすることもできます。 さらに、それを呼び出すことによってレポートを生成するので、すべてを1行に収めることができます(RMDの呼び出しが関数内にある場合、入力した変数が欠落していることがわかりますが、レポートはそれでも正しく公開される)

概要

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





knitr