Knit pdf from rmd script by clicking an executable

2019-02-09 20:44发布

问题:

Synopsis

I would like to produce a pdf file from an rmd script just by clicking a file / an icon so that my coworkers don't exhaust themselves by opening RStudio first.

The question

When I saw this on R-bloggers, and got it working, I thought I was approaching the perfect work flow from scripting to sharing my work by letting my coworkers execute a file and get a pdf with updated numbers as a result. However, I can't get it to work with some of the functions in the knitr library.

Best case scenario is that this question is interesting to only a few of you out there, but here goes:

Below you can see a script in a file called RexecKnit.Rmd. The only reason it's there is so you can test the whole procedure for yourselves if you want to. By the way, I'm running RStudio Version 0.99.467 on Windows 7, 64 bit.

---
title: "Executable R, rmd and pdf"
header-includes: \usepackage{caption} \usepackage{fancyhdr}
output: pdf_document
fig_caption: no
---

\addtolength{\headheight}{0.5cm} 
\pagestyle{fancyplain} 
\renewcommand{\headrulewidth}{0pt}

```{r Settings, echo = FALSE, eval = TRUE, results = "hide", warning = FALSE, message = FALSE}
rm(list=ls())

pck_loaded <- (.packages())

# Packages to load
pck_toload <- c('ggplot2', 'xts', 'quantmod', 'zoo', 'PerformanceAnalytics',
            'tseries', 'mvtnorm', 'data.table', 'XLConnect', 'sqldf', 'stargazer', 'xtable', 'gridExtra', 'grid', 'TTR')

# Load packages
for(i in 1:length(pck_toload)) {
   if (!pck_toload[i] %in% pck_loaded)
    print(pck_toload[i])
    library(pck_toload[i], character.only = TRUE)
}

```

\captionsetup[table]{labelformat=empty}

```{r repex1, echo = FALSE, eval = TRUE, results = "asis", warning = FALSE, message = FALSE, fig.width = 12, fig.height = 8}

# Data table with formatted numbers and text
v1 <- c("\\colorbox{white}{0.05}" , "\\colorbox{yellow}{0.57}", "\\colorbox{red}{-0.99}")
v2 <- c("An unexpected comment", "A qurious question", "And an insightful answer")
dt1 <- data.table(v1,v2)

# Data table using xtable
print(xtable(dt1,
      caption = 'Fancy table'),
      caption.placement = 'top',
      comment = FALSE,
      sanitize.text.function = function(x) x)
```

```{r repex2, echo = FALSE, eval = TRUE, results = "asis", warning = FALSE, message = FALSE, fig.width = 12, fig.height = 8}

# Data table wiht random numbers
dt2 <- data.table(replicate(2,sample(0:100,10,rep=TRUE)))

# ggplot of random numbers
plx <- ggplot(data=dt2 ,aes(x=V1, y = V2))
plx <- plx + geom_line(color = 'blue', fill = 'grey')
plx <- plx + theme_classic()
plx <- plx + labs(title="Random numbers", x="x-axis",y="y-axis")
plot(plx)
```

I know that's a pretty lengthy script for testing purposes, but it's just to make sure that everything works when I execute the script upon double clicking this little beauty which is a file called caller knitr.Rexe (like in the R-Bloggers post) containing this little piece of code:

library(knitr)
library(rmarkdown)
setwd('C:/repos/r_tutorials/executable R files')
knit('RexecKnit.Rmd')
Sys.sleep(3)

And this works as expected. Upon double klicking the file, the script is run without opening R or Rstudio, and a .md file is produced in the desired folder. And the same script works when it's stored as a .Rexe file and as a .R file. But here's the problem:

I want to produce a pdf, and according to a tip here, replacing

knit('RexecKnit.Rmd')

with

rmarkdown::render("RexecKnit.Rmd")

should do the trick as long as the YAML header includes this:

output: pdf_document

And it does work (meaning that the pdf is created with every detail specified in the lenghty script), at least when it is run as an .R file. To my disappointment, it does NOT work when it is run from a .Rexec file like this:

library(knitr)
library(rmarkdown)
setwd('C:/repos/r_tutorials/executable R files')
rmarkdown::render("RexecKnit.Rmd")
Sys.sleep(3)

Thank you for having a look at this!

回答1:

Assuming one has independently installed pandoc on Windows machine (which turned out to be the root of the problem in this case), she can do it in the following manner:

First: make a .R file with the content like below

library(knitr)
library(rmarkdown)
setwd('C:/repos/r_tutorials/executable R files')
knit("RexecKnit.Rmd")

# render the generated markdown file.
render("RexecKnit.md")

Sys.sleep(3)

Second: make a .bat file

Create a .bat file, say "my_bat_file.bat", and include the text below. However, the paths have to be adjusted:

"C:\R\R-3.2.2\bin\x64\R.exe" CMD BATCH --vanilla --slave "C:\path_to_your_file\your_file.R" "C:\path_to_your_file\your_file.Rout"

Third: Instruct Windows Task Scheduler

If the data is updated frequently, one can shedule the Task Scheduler in Windows to repeatedly execute the .bat file once a week at certain time at night, so reports are there in the morning.