Knitr:使用嵌套循环生成多个报告
Knitr: Use nested loops to generate multiple reports
A previous post on Whosebug 提供了关于如何使用模板 .Rnw 文件生成多个报告的非常有用的指南。我想复制这个,除了我有 4 个循环,而不仅仅是示例中使用的循环。
就我而言,这些是我用来生成报告的循环:
最外层循环:遍历包含我要分析的变量名称的向量
内部 3 个循环:循环遍历不同的 seasons/geographic 位置
这是模板代码的示例,当我提供循环中提供的所有必要变量时,它可以正常工作:
\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'))
但我收到以下错误,可能是因为我有多个级别的循环,这些循环都使用相同的块标签名称作为数字的引用:
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) 模板文件不能有 \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-examples 部分,特别是 this one。
A previous post on Whosebug 提供了关于如何使用模板 .Rnw 文件生成多个报告的非常有用的指南。我想复制这个,除了我有 4 个循环,而不仅仅是示例中使用的循环。
就我而言,这些是我用来生成报告的循环:
最外层循环:遍历包含我要分析的变量名称的向量
内部 3 个循环:循环遍历不同的 seasons/geographic 位置
这是模板代码的示例,当我提供循环中提供的所有必要变量时,它可以正常工作:
\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'))
但我收到以下错误,可能是因为我有多个级别的循环,这些循环都使用相同的块标签名称作为数字的引用:
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) 模板文件不能有 \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-examples 部分,特别是 this one。