Rmarkdown not outputting results of system command to html file - r

I'm new to using Markdown, and have looked for a similar problem to this on SO without success. I'm using Rmarkdown (with Rstudio and knitr) to write a vignette that describes reading in a datafile which is imported as part of the package. I can correctly access the datafile using
> system.file("extdata", "Marlin-tag38606.txt", package = "xtractomatic")
I want to show the first few lines of this file in the vignette, so my code reads
```{r, results=as.is}
datafile <- system.file("extdata", "Marlin-tag38606.txt", package = "xtractomatic")
system(paste("head -n5 ",datafile))
```
The problem is that the results of this call are output to the Rmarkdown console and NOT to the vignette html file.
The output in the Rmarkdown window of RStudio is (but formatted nicer):
|................... | 29%
label: unnamed-chunk-8
date lon lat lowLon higLon lowLat higLat
4/23/2003 203.899 19.664 203.899 203.899 19.664 19.664
4/24/2003 204.151 19.821 203.912597 204.389403 18.78051934 20.86148066
4/30/2003 203.919 20.351 203.6793669 204.1586331 18.79728188 21.90471812
5/1/2003 204.229 20.305 203.9943343 204.4636657 18.90440013 21.70559987
|.................... | 31%
Which is what I wanted outputted to the vignette text, but it is not there. Within the resulting vignette all I have is the two lines of R code, but not the output from the system call.
Any advice would be appreciated. Thanks.
Cara Wilson

Use intern = TRUE for system(), then cat() the output:
cat(system(paste("head -n5", datafile), intern = TRUE), sep = '\n')

Using a bash chunk in the Rmarkdown document does the job for me.
For example with the package testdat which has .csv file in its extdata directory:
```{bash}
head -n5 ~/R/x86_64-pc-linux-gnu-library/3.3/testdat/extdata/2012.csv
```
will give in your html file:
## 14,,2012,Censo,1775351,,
## 14,,2012,Votantes,1135568,64.0,
## 14,,2012,Nulos,9168,0.8,
## 14,,2012,Válidos,1126400,99.2,
## 14,,2012,Blancos,14640,1.3,
I am not sure though this option existed in 2014 when you've asked the question.

Related

Putting an R command that generates an error in an R markdown file

I am typing up some results comparing various methods for importing unicode files in R. I read in a CSV file using dplyr::read_csv() and utils::read.csv(), then compare them using dplyr::setdiff(). In fact, the two data files are different because the column names are read differently by the default options of the two methods. This causes an error to be written to the console. I know how to fix the error itself; that is not the issue. The three commands in the markdown file are
```{r read.csv message=FALSE, warning=FALSE, error=FALSE}
dplyr_read_csv <- read_csv("World Class.csv")
base_read_csv_T <- read.csv("World Class.csv")
setdiff(dplyr_read_csv, base_read_csv_T)
```
..which, when run as an R script result in:
> setdiff(dplyr_read_csv, base_read_csv_T)
Error in `setdiff()`:
! `x` and `y` are not compatible.
✖ Cols in `y` but not `x`: `height..in..`, `weight..lb..`, `height..cm..`,
`weight..kg..`, `中文..Simplified.`, `中文..Traditional.`, `English..GB.`,
`English..US.`, `Русский.язык`, `Tiê.ng.Viê.t`.
✖ Cols in `x` but not `y`: `height (in.)`, `weight (lb.)`, `height (cm.)`, `weight
(kg.)`, `中文 (Simplified)`, `中文 (Traditional)`, `English (GB)`, `English
(US)`, `Русский язык`, `Tiếng Việt`.
I would like for this error to show in the generated output.
When I put the code in the R markdown file, the file will not knit because of this thrown error. I have done the obvious things like putting error = FALSE in the R chunk, but none of my efforts have worked.
You can find the data file (named World Class.csv) and the R markdown file (read_world_classes.Rmd) in my github repository. What should I do to include this chunk and its error in the markdown file?
(There is a regular R script read_world_classes.R that I initially made to compare a bunch of other file types aside from CSV. That's what all the other files in the repository are).
As #bs93 said above, the correct output is obtained by adding error=TRUE to the r chunk:
```{r error=true}
<code goes here>
```

Unable to Import .Rdata to RMarkdown

I use Windows and try to read .Rdata file to RMarkdown using rio's import function. It keeps giving me errors. This works just fine when I'm using R code in the same folder.
So here is the code in the first RMarkdown code chunk
{r setup, include = FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(tidyverse)
library(rio)
df_clean <- import("data/df_clean.rdata")
Error in import("data/df_clean.rdata") : No such file
Is there a different between using R Code or RMarkdown? This also works fine when I type it in the R console, but doesn't work in the R Code chunk in the RMarkdown.
When I check in the working directory, the file is there
> getwd()
[1] "C:/Users/Project/Project A"
> list.files()
[1] "code" "data"
[3] "documentation" "output"
> list.files("data")
[1] "archive" "df_clean.rdata" "df_unique.rdata"
I'm new to R and just start coding this year. I hope I can do my EDA in RMarkdown to become more organized. Kindly help me with the question format if I did not posted it correctly.
if you unsure of the file path of the RData to import, use this to make Selection manually first..
df_clean <- import(file.choose())
or you can also get the full path of your RData stored in variable by doing:
RData_path <- file.choose()
df_clean <- import(RData_path)

How can I make the output of my function (several ggplot2 graphs) an html file (displaying those graphs)?

I'm writing a personal use package which trains/tests models, and finally runs a myriad of LIME and DALEX explanations on them. I save these as their own ggplot2 objects (say lime_plot_1), and at the end of the function these are all returned to the global environment.
However, what I would like to have happen is that, at the end of the function, not only would I have these graphs in the environment but a small html report would also be rendered - containing all the graphs that were made.
I would like to point out that while I do know I could do this by simply using the function within an Rmarkdown or Rnotebook, I would like to avoid that as I plan on using it as an .R script to streamline the whole process (since I'll be running this with a certain frequency), and from my experience running big chunks in .Rmd tends to crash R.
Ideally, I'd have something like this:
s_plot <- function(...){
1. constructs LIME explanations
2. constructs DALEX explanations
3. saves explanations as ggplot2 objects, and list them under graphs_list
4. render graphs_list as an html file
}
1, 2, and 3 all work but I haven't found a way to tackle 4. that doesn't include doing the whole process in a .Rmd file.
EDIT: Thanks to #Richard Telford's and #Axeman's comments, I figured it out. Below is the function:
s_render <- function(graphs_list = graphs_list, meta = NULL, cacheable = NA){
currentDate <- Sys.Date()
rmd_file <- paste("/path/to/folder",currentDate,"/report.Rmd", sep="")
file.create(rmd_file)
graphs_list <- c(roc_plot, prc_plot, mp_boxplot, vi_plot, corr_plot)
c(Yaml file headers here, just like in a regular .Rmd) %>% write_lines(rmd_file)
rmarkdown::render(rmd_file,
params = list(
output_file = html_document(),
output_dir = rmd_file))}
First, create a simple Rmarkdown file, that takes a parameter. The only objective of this file is to create the report. You can for instance pass a file name:
---
title: "test"
author: "Axeman"
date: "24/06/2019"
output: html_document
params:
file: 'test.RDS'
---
```{r}
plot_list <- readRDS(params$file)
lapply(plot_list, print)
```
I saved this as test.Rmd.
Then in your main script, write the plot list to a temporary file on disk, and pass the file name to your markdown report:
library(ggplot2)
plot_list <- list(
qplot(1:10, 1:10),
qplot(1:10)
)
file <- tempfile()
saveRDS(plot_list, file)
rmarkdown::render('test.Rmd', params = list(file = file))
An .html file with the plots is now on your disk:

How to create multiple PDFs with different content from a single data frame?

Problem
I want to knit multiple PDFs from a single data frame. Therefore I've tried various solutions, but my knowledge in R, R Studio, LaTex, knitr is very limited so I wasn't able to adapt some solution approaches and finally tried it on my own. I actually think my code is absolutely not the way you actually use to achieve what I want to achieve. So, please feel free to tell me where and what I can/should improve.
I would be really grateful for some help. I've been googling for hours now and I would also appreciate if you could recommend me any tutorial/guide/explanation. I don't even know where to start.
Current State: Solved
Code
main.R
for(i in 1:nrow(mtcars)) {
g_title <- rownames(mtcars)[i]
knit2pdf(input = "main.Rnw",
output = paste0("output\\", g_title, ".pdf"),
quiet = FALSE,
envir = parent.frame())
}
template.Rnw
\documentclass{article}
\usepackage[ngerman]{babel}
\begin{document}
\begin{titlepage}
Titlepage
\end{titlepage}
\tableofcontents
\newpage
\section{Topic 1}
\newpage
\section{Topic 2}
\end{document}
Solution Approaches
Global Variables
I tried to create global variables which are altered by a for loop. These variables are then used in the .Rnw file in form of a function. I wasn't able to get this working due unknown errors.
Code in the .R file:
printPlot <- function() {
print(g_plot)
}
for(i in 1:nrow(mtcars)) {
g_title <- rownames(mtcars)[i]
g_plot <- ggplot(mtcars[i,], aes(x = cyl, y = disp) ) +
geom_point()
knit2pdf(input = "main.Rnw",
output = paste0("output\\", g_title, ".pdf"),
quiet = FALSE,
envir = parent.frame())
}
Code in the .Rnw file:
<<>>=
printPlot()
#
Errors:
The PDFs are created, but their contents are messed up. You can see it in the image under 'Current State'.
I also receive several error/warning messages, e.g.:
Warning messages:
1: running command '"C:\Users\Marc\AppData\Local\Programs\MIKTEX~1.9\miktex\bin\x64\texify.exe"
--quiet --pdf "Mazda RX4.pdf" --max-iterations=20 -I "C:/PROGRA~1/R/R-33~1.2/share/texmf/tex/latex" -I
"C:/PROGRA~1/R/R-33~1.2/share/texmf/bibtex/bst"' had status 1
2: running command '"C:\Users\Marc\AppData\Local\Programs\MIKTEX~1.9\miktex\bin\x64\texify.exe"
--quiet --pdf "Mazda RX4 Wag.pdf" --max-iterations=20 -I "C:/PROGRA~1/R/R-33~1.2/share/texmf/tex/latex" -I
"C:/PROGRA~1/R/R-33~1.2/share/texmf/bibtex/bst"' had status 1
MakeFile
I just read the first time about makefile. Maybe this could help solving the problem.
If I got it right makefile is used with Markdown and not directly with LaTex. This seems to be a massive loss in performance. This point is quite important to me, so I will try to find another solution.
Other SO Questions
In most of the cases I tried to adapt the code, but simply failed, because I am missing knowledge to understand the given solution approaches.
R Knitr PDF: Is there a posssibility to automatically save PDF reports (generated from .Rmd) through a loop?
Using loops with knitr to produce multiple pdf reports… need a little help to get me over the hump
Can Sweave produce many pdfs automatically?
From the question, I'm not entirely sure about the expected output, but there concept is clear. And although the task itself is quite simple, surprisingly many things can go wrong.
Code:
code.R
library(knitr)
library(ggplot2)
dir.create(path = "output/")
opts_knit$set(base.dir = "output/")
for(i in 1:nrow(mtcars)) {
filename <- rownames(mtcars)[i]
knit(input = "template.Rnw", output = paste0("output/", filename, ".tex"))
tools::texi2pdf(paste0("output/", filename, ".tex"), clean = TRUE)
file.copy(from = paste0(filename, ".pdf"), to = paste0("output/", filename, ".pdf"))
# file.remove(paste0(filename, ".pdf")) # this will DELETE filename.pdf from the current working directory (should be safe because we just created this file)
}
template.Rnw
\documentclass{article}
\begin{document}
<<>>=
ggplot(mtcars[i,], aes(x = cyl, y = disp) ) + geom_point()
#
\end{document}
We need to set base.dir because the current working directory is one level above the directory where the document is created. This would lead to wrong figure paths: knitr produces the plots in figure/ but they should be in output/figure/. Consequently, compilation will fail.
For some reason knit2pdf cannot compile the generated intermediate TEX file. Therefore I use knit to produce a TEX file and then tools::texi2pdf to compile this file to PDF.
Note how variables from code.R are visible to the code in the template document. That's why i can be used in template.Rnw.

Non-valid bibtex from knitr write_bib

I'm trying to get knitr to create a bibtex file that includes all the packages that I am using as shown (and answered) in this question. That part is working fine but a single R package, foreach, results in non-valid bibtex code.
Here is a minimal .Rnw example that produces the error
\documentclass[11pt]{article}
\usepackage{natbib}
\begin{document}
This is a test
<<>>=
library(foreach)
# Write the bibtex file:
write_bib("foreach", file="test.bib")
#
\nocite{*}
\bibliographystyle{apalike}
\bibliography{test}
\end{document}
kniting this file produces this test.bib file
#Manual{R-foreach,
title = {foreach: Provides Foreach Looping Construct for R},
author = {{Revolution Analytics} and Steve Weston}},
year = {2015},
note = {R package version 1.4.3},
url = {https://CRAN.R-project.org/package=foreach},
}
Note that the author line has two curly braces towards the end of the author line so using this bibtex file without removing the curly brace results in a bunch of problems. I've only encountered this problem with the foreach package.
Can anyone tell me what I can do to prevent the error (currently I have a one-line sed code to remove the extra brace)?
The citation("foreach") output looks fine and dandy, so I'm guessing the error may be deep down in utils:::toBibtex.bibentry but I haven't been able to figure it out.

Resources