2016-08-16 56 views
0

對於如何使用模板.Rnw文件生成多個報告,A previous post on StackOverflow有一個非常有用的指導。我想重複這個,除了我會有4個循環,而不僅僅是這個例子中使用的循環。Knitr:使用嵌套循環生成多個報告

在我而言,這些都是我用來產生報告的循環:

  • 最外層循環:通過包含我要分析

  • 的變量名稱的向量循環
  • 內部3個循環:通過不同的季節的循環/地理位置

這裏是模板代碼的一個示例,它沒有任何問題的工作原理,當我供給所有將在迴路中提供了必要的變量:

\begin{document} 
This is a test in which the \texttt{\Sexpr{varname}} variable is used in this report. If successful, further reports can be generated using a loop with this same script! 

First, a plot of the CDFs, with Kolmogorov-Smirnov statistics: 
\begin{figure}[h] 
\centering 
<<cdf-plots,dev='png',out.width='0.5\\linewidth',echo=FALSE,warning=FALSE,fig.align='centering'>>= 
chart_stats(varname,data_vec,labs,season,s,h,colvec=colvec,cdf_plot=TRUE) 
cap1=paste('Cumulative distribution functions for the counts,',season,s,h) 
@ 
\caption{\Sexpr{cap1}} 
\end{figure} 
<<ks_calc,warning=FALSE,results='asis',echo=FALSE>>= 
library(xtable) 
ks=chart_stats(varname,data_vec,labs,season,s,h,ks_test=TRUE,dval=TRUE) 
cap=paste('D-values for',season,h,s) 
print(xtable(ks,caption=cap)) 
@ 

爲了能夠看到我的輸出的緣故,每個文件目前作爲一個單獨的文件.tex如圖生成:

library(knitr) 
setwd("~/data_netcdf") 
load("loaded_data.Rdata") 
source("~/tempestextremes/test/chart_stats.R") 

data_vec<-c("ERA", "climo", "2xCO2","SSTplus2","SSTplus2_2xCO2") 

seasons_vec<-c("DJF","JJA","MAM","SON") 
sec=c("ATL","PAC") 
hemi=c("NH","SH") 
var=c('centlat','centlon','area') 

for (varname in var){ 
    } 
    for (season in seasons_vec){ 
    for (h in hemi){ 
     for (s in sec){ 
     output_name=paste(varname,'_',season,'_',h,'_',s,'_report.tex',sep="") 
     knit2pdf("~/data_netcdf/report_test.Rnw",output=output_name) 
     } 
    } 
    } 
} 

還有就是利用孩子的文件,以輸出組合成一個文件,這聽起來類似於想什麼,我做的,這裏knitr例子就是我已經試過:

<<test-main,include=FALSE>>= 
[removed for length] 

#testing on just one variable name 
var=c('centlat') 
for (varname in var){ 
    out=NULL 
    for (season in seasons_vec){ 
    for (h in hemi){ 
     for (s in sec){ 
     out=c(out,knit_child("~/data_netcdf/report_test.Rnw")) 
     } 
    } 
    } 
} 
@ 

\Sexpr(paste(out,collapse='\n')) 

b UT我收到以下錯誤,可能是由於這樣的事實,我有一個都使用相同的塊標籤的名稱用作引用的數字環路的多個層面:

Error in parse_block(g[-1], g[1], params.src) : 
    duplicate label 'cdf-plots' 
Calls: knit ... process_file -> split_file -> lapply -> FUN -> parse_block 

能有人請解釋這個錯誤信息?我是否需要以某種方式更改標籤名稱,以便在每次循環時區分它們?或者我應該在模板文件中實現3個內部循環?或者,也許在事實之後結合所有.tex文件?

我希望能幫助您找出最佳的工作流程。

+1

您確實需要區分標籤名稱,以便它們在每次循環時都不相同。這是否幫助你http://stackoverflow.com/questions/12095113/r-knitr-possible-to-programmatically-modify-chunk-labels? – Tutuchan

+0

我用'knit_expand'成功評估了我在循環中設置的'prefix'變量,但我無法弄清楚如何將它與'knit_child'結合起來(或者我應該甚至使用'knit_child ')。有什麼想法嗎? – pianoplunkster

+1

看起來像你找到解決方案!正如你所看到的,如果你使用'knit_expand',你不需要'knit_child'。 – Tutuchan

回答

1

我想出了一個解決方案!一些注意事項:

1)模板文件不能有\begin{document}...\end{document}標籤或任何前導碼,這必須在主.Rnw文件中。

2)就目前而言,它僅適用於單個變量(而不是循環遍歷變量向量),但將其擴展是一件微不足道的事情。

因此,這裏是模板的一個例子:

<<{{prefix}}-setup>>= 
varname='{{varname}}' 
season='{{season}}' 
h='{{h}}' 
s='{{s}}' 
@ 

First, a plot of the CDFs, with Kolmogorov-Smirnov statistics: 
\begin{figure}[h] 
\centering 
<<'{{prefix}}-cdf-plots',dev='png',fig.lp='{{prefix}}',out.width='0.5\\linewidth',echo=FALSE,warning=FALSE,fig.align='centering'>>= 
colvec=c("blue","red","green","purple","pink") 
chart_stats(varname,data_vec,labs,season,s,h,colvec=colvec,cdf_plot=TRUE) 
cap1=paste('Cumulative distribution functions for the counts,',season,s,h) 
@ 
\caption{\Sexpr{cap1}} 
\end{figure} 

然後主文檔:

\documentclass{article} 
\usepackage[margin=0.5in]{geometry} 
\begin{document} 

<<test-main,include=FALSE>>= 
library(knitr) 
setwd("~/data_netcdf") 
load("loaded_data.Rdata") 
source("~/tempestextremes/test/charts_stats.R") 
[other stuff] 
@ 
... 
<<generate-code,echo=FALSE>>= 
    varname='centlat' 
    out=NULL 
    for (season in seasons_vec){ 
    for (h in hemi){ 
     for (s in sec){ 
     prefix=paste(season,h,s,sep="_") 
     out=c(out,knit_expand("~/data_netcdf/report_test_1.Rnw")) 
     } 
    } 
    } 
@ 

\Sexpr{paste(knit(text=out),collapse='\n')} 
\end{document} 

我要指出的是,靈感來自於knitr-例子節來了,特別是this one