为了账号安全,请及时绑定邮箱和手机立即绑定

使用带有knitr的循环来生成多个pdf报告…需要一点帮助,以帮助我克服麻烦

使用带有knitr的循环来生成多个pdf报告…需要一点帮助,以帮助我克服麻烦

拉莫斯之舞 2019-12-26 10:59:06
首先,我必须承认,我很新的knitr和重现性分析的概念,但我可以看到在提高我当前的工作流程(其中包括很多的复制粘贴到Word文档)它的潜力。我经常用组(医院在本例中),以产生多个报告和每家医院内,可能会有许多不同的病房说我汇报的结果。以前我使用循环跑了我所有的情节和分析在R,然后复制/粘贴工作开始; 但是,在阅读了这篇文章(Sweave可以自动产生许多pdf吗?)之后,它给了我希望,我实际上可以跳过很多步骤,直接从R直接通过Rnw / knitr报告。但是,尝试一下之后,我发现有些东西还没有完全解决(因为Rnw中的R环境似乎无法识别我要传递给它的循环变量?)。   ##  make my dataHospital <- 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/pastefor(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}想经营我的编织()的代码块后,我得到这个错误:Error in file(con, "w") : invalid 'description' argument当我看着在* .tex文件是要创建的目录,我可以看到从医院A中的2个PDF地块被生产(无为B),并没有医院具体* .tex文件编织成PDF。预先感谢您可以提供任何帮助!
查看完整描述

3 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

您不需要重新定义.Rnw文件中的数据,并且我认为警告来自于以下事实:将输出名称与Hospital(医院的完整向量)而不是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'))

}


查看完整回答
反对 回复 2019-12-26
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

好问题!这对我来说与您在问题中提供的其他内容一起起作用。请注意,我已将您替换hosp为just x。我叫你的Rnw文件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))

我已经更换了你的循环lapply和匿名函数,这似乎往往被认为更R-ish。


在这里你能看到我更换了hosp与x中rnw文件:


\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}

结果是两个TEX文件(report_A.tex,report_B.tex),四个PDF文件的数字(A1,A2,B1,B2)和用于报告2页的PDF(report_A.pdf,report_B.pdf),每个具有其数字在他们之中。那是你的追求吗?


查看完整回答
反对 回复 2019-12-26
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

在这个答案中,我打算回答一个更笼统的问题:“使用循环生成多个pdf报告”,而不是您的特定示例。这是因为作为菜鸟很难遵循这种趋势。我设法使其最终能够工作(html版本),所以这是我的谦虚解决方案。这里可能出版了一些更好的书,我只是还不完全了解它们。


使用您的设计创建RMD文件,并将其保存在working \ input目录中(在Rstudio中:file-> newfile-> R markdown)。该文件应包括在报告中绘制图表所需的所有功能(只需在这些代码块之一中声明它们)。认为此文件作为模板所有报告的。不必担心在更早地将数据整理好之后将数据传递到环境中的问题-我将在(2)中进行介绍。要理解的关键问题是所有计算都在管道的更深处完成(在呈现RMD文件的那一刻)。


在不同的控制r文件中创建您需要使用的循环。在我的情况下,有一个循环遍历目录中的所有文件,并将它们放入数据帧。然后我想将这些数据框以及其他数据变量传递到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))}

   }


最重要的命令是render函数调用。它允许您将所需的任何参数放入RMD环境。它还允许您更改报告的名称并更改输出位置。此外,通过调用它,您还可以生成报告,因此可以将其全部收集在一行中。(请注意,如果对RMD的调用在一个函数中,则可能会发现输入的变量丢失了,但是报告会仍然可以正确发布)


摘要

您需要两个文件-RMD文件,它将是所有其他报告的模板和一个控制文件。控制文件将获取数据,将其修改,然后将修改后的参数传递给RMD(通过render函数)。RMD获取数据,进行一些计算,将其绘制并发布到新文件中(也通过render函数)。希望我能帮上忙。


查看完整回答
反对 回复 2019-12-26
  • 3 回答
  • 0 关注
  • 748 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信