How to remove display of strange characters in R-Markdown chunk output? - r

I am getting frequencies from a few rasters and am doing so in R-Markdown. I am using lapply to get the frequencies from the rasters in a list. When I store those frequencies in a list of data.frames, the chunk output displays some unexpected non-numeric characters.
Example rasters:
```{r}
require(raster)
r1 <- setValues(raster(nrows = 10, ncols = 10), sample(1:10, 100, replace = TRUE))
r2 <- setValues(raster(nrows = 10, ncols = 10), sample(1:10, 100, replace = TRUE))
rList <- list(r1, r2)
```
Getting the frequencies:
```{r}
lapply(rList, function(ras) {
data.frame(freq(ras))
})
```
Output from the above chunk:
If I display only the data frame itself, those characters are not displayed:
```{r}
lapply(rList, function(ras) {
data.frame(freq(ras))
})[[2]]
```
The correct values are also shown if do not use data.frame:
```{r}
lapply(rList, function(ras) {
freq(ras)
})
```
I've tried saving the Rmd with UTF-8 encoding and am on RStudio 1.2.5019. Any ideas on how to get the list of data frames to display properly would be appreciated.
Edit: Just a note that the characters do not display in any scenario in the generated html file, only in the specific chunk in the R Notebook file itself.
Edit 2:
The full code and YAML header for the notebook that generates the strange characters is below:
---
title: "R Notebook"
output: html_notebook
---
```{r}
require(raster)
r1 <- setValues(raster(nrows = 10, ncols = 10), sample(1:10, 100, replace = TRUE))
r2 <- setValues(raster(nrows = 10, ncols = 10), sample(1:10, 100, replace = TRUE))
rList <- list(r1, r2)
```
```{r}
lapply(rList, function(ras) {
data.frame(freq(ras))
})
```
```{r}
lapply(rList, function(ras) {
data.frame(freq(ras))
})[[2]]
```

Check out this code is properly showing the output. You can use print
On previewing the html notebook output is not showing any UTF characters
If you want to use the chunk output than you can use
as.data.frame()

I've had this experience before with that same "ÿ" character, but haven't thought about it a lot (Mac RStudio). I have been able to re-run my code and haven't been able to reproduce it on the same chunk, even in the same session.
I do use the formattable package often, and since folks are mentioning the formatting aspect, perhaps that's at play? Although it's hard for me to envision exactly how.
I did find these related items about Pandoc rendering Unicode artifacts on certain character inputs, and about Pandoc converting to UTF-8. Since the workflow involves knitr feeding Pandoc, maybe that's a piece?
https://github.com/jgm/pandoc/issues/844
https://yihui.org/en/2018/11/biggest-regret-knitr/
Can't quite connect the dots, but hope it helps someone else put it together.
I don't remember it happening recently, so potentially one avenue is to update pandoc and knitr (or even RStudio altogether -- I'm on 1.2.5019)?

Related

RMarkdown: ggplot into a table

There are already a few questions considering ggplots in RMarkdown but none has answered my question as how to put a ggplot into a table with kable() by knitr.
I ve tried this link:
How can I embed a plot within a RMarkdown table?
But have not had any luck so far. Any ideas?
The idea was to put all plots into a list with
a<-list(p1,p2,p3...)
and then having the table with
{r}kable(a)
Additional text should also be able to be included
b<-("x","y","z",...)
kable (c(a,b),col.names=c())
Thanks for your help
Frieder
I experimented some with this and the following is the best I could come up with. This is a complete markdown document you should be able to paste into RStudio and hit the Knit button.
Two relevant notes here.
Setting the file links directly into kable doesn't work as it is wrapped in html such that it is interpreted as text, so we need to gsub() it in. An alternative is to set kable(..., escape = FALSE), but it is a risk that other text might cause problems.
Also, the chunk option results = 'asis' is necessary to have the print(kab) return raw html.
I don't know if these are problems for the real application.
---
title: "Untitled"
author: "me"
date: "02/06/2020"
output: html_document
---
```{r, results = 'asis'}
library(ggplot2)
library(svglite)
n <- length(unique(iris$Species))
data <- split(iris, iris$Species)
# Create list of plots
plots <- lapply(data, function(df) {
ggplot(df, aes(Sepal.Width, Sepal.Length)) +
geom_point()
})
# Create temporary files
tmpfiles <- replicate(n, tempfile(fileext = ".svg"))
# Save plots as files, get HTML links
links <- mapply(function(plot, file) {
# Suit exact dimensions to your needs
ggsave(file, plot, device = "svg", width = 4, height = 3)
paste0('<figure><img src="', file, '" style = "width:100%"></figure>')
}, plot = plots, file = tmpfiles)
# Table formatting
tab <- data.frame(name = names(plots), fig = paste0("dummy", LETTERS[seq_len(n)]))
kab <- knitr::kable(tab, "html")
# Substitute dummy column for figure links
for (i in seq_len(n)) {
kab <- gsub(paste0("dummy", LETTERS[i]), links[i], kab, fixed = TRUE)
}
print(kab)
```
I have found my way around it as described in the link I posted.
I. Saved my plot as a picture
II. Used sprintf() to insert picture into table with this command from Rmarkdown:
![](path/to/file)
Poor, but it works. If anybody finds a solution, I will always be interested in smart coding.

How to export an xtable as PDF directly via R script?

I have a data.frame that I need as a nice PDF table for a scientific poster. While it's very easy to export plots via pdf(), I'm stuck with this table.
I know how to get a PDF table with rmarkdown, e.g.
---
output: pdf_document
---
```{r tab, echo=FALSE, results='asis'}
library(xtable)
xtable(head(mtcars))
```
But I want this output directly from the R script, e.g.
renderThisToPDF(xtable(head(mtcars), to="nicetable.pdf") # fantasy code
How would I do this?
So far I attempted this code with a indirection via writeLines
code <- "library(xtable)\nprint(xtable(head(mtcars)))"
fileConn <- file("output.Rmd")
writeLines(cat("---\noutput: pdf_document\n---\n```{r tab, echo=FALSE, results='asis'}\n",
code, "\n```\n"), fileConn)
close(fileConn)
knitr::knit('output.Rmd')
but failed with an error.
Error in writeLines(cat("---\noutput: pdf_document\n---\n```{r tab, echo=FALSE,
results='asis'}\n", :
can only write character objects
I guess there's probably an easier solution?
Here is a possibility, without rmarkdown.
library(xtable)
latex <- print.xtable(xtable(head(iris)), print.results = FALSE)
writeLines(
c(
"\\documentclass[12pt]{article}",
"\\begin{document}",
"\\thispagestyle{empty}",
latex,
"\\end{document}"
),
"table.tex"
)
tools::texi2pdf("table.tex", clean = TRUE)
Or, using the standalone document class:
latex <- print.xtable(xtable(head(iris)), print.results = FALSE,
floating = FALSE)
writeLines(
c(
"\\documentclass[12pt]{standalone}",
"\\usepackage{caption}",
"\\begin{document}",
"\\minipage{\\textwidth}",
latex,
"\\captionof{table}{My caption}",
"\\endminipage",
"\\end{document}"
),
"table.tex"
)
tools::texi2pdf("table.tex", clean = TRUE)
One Solution would be to use tableGrob from gridExtra, add the table to a grid plot and save it with ggsave
require(ggplot2)
require(gridExtra)
ds <- iris[1:10, ]
tg <- tableGrob(ds)
ggsave("test.pdf", tg)
This is quite simple but will be less convinient than a LaTeX solution for more complex tables.
Here is a one-liner using the huxtable package (disclaimer: I am the author)
huxtable::quick_pdf(iris[1:10, ])
It will automatically open the PDF in your viewer – you can disable this with auto_open=FALSE.
For prettier formatting, create a huxtable object:
library(huxtable)
ht <- as_hux(iris[1:10, ])
bold(ht)[1,] <- TRUE # or whatever else you feel like doing
quick_pdf(ht)

rstudio hangs and aborts with rmarkdown loop

I have several datasets each of which have a common grouping factor. I want to produce one large report with separate sections for each grouping factor. Therefore I want to re-run a set of rmarkdown code for each iteration of the grouping factor.
Using the following approach from here doesnt work for me. i.e.:
---
title: "Untitled"
author: "Author"
output: html_document
---
```{r, results='asis'}
for (i in 1:2){
cat('\n')
cat("#This is a heading for ", i, "\n")
hist(cars[,i])
cat('\n')
}
```
Because the markdown I want to run on each grouping factor does not easily fit within one code chunk. The report must be ordered by grouping factor and I want to be able to come in and out of code chunks for each iteration over grouping factor.
So I went for calling an Rmd. with render using a loop from an Rscript for each grouping factor as found here:
# run a markdown file to summarise each one.
for(each_group in the_groups){
render("/Users/path/xx.Rmd",
output_format = "pdf_document",
output_file = paste0(each_group,"_report_", Sys.Date(),".pdf"),
output_dir = "/Users/path/folder")
}
My plan was to then combine the individual reports with pdftk. However, when I get to the about the 5th iteration my Rstudio session hangs and eventually aborts with a fatal error. I have ran individually the Rmd. for the grouping factors it stops at which work fine.
I tested some looping with the following simple test files:
.R
# load packages
library(knitr)
library(markdown)
library(rmarkdown)
# use first 5 rows of mtcars as example data
mtcars <- mtcars[1:5,]
# for each type of car in the data create a report
# these reports are saved in output_dir with the name specified by output_file
for (car in rep(unique(rownames(mtcars)), 100)){
# for pdf reports
rmarkdown::render(input = "/Users/xx/Desktop/2.Rmd",
output_format = "pdf_document",
output_file = paste("test_report_", car, Sys.Date(), ".pdf", sep=''),
output_dir = "/Users/xx/Desktop")
}
.Rmd
```{r, include = FALSE}
# packages
library(knitr)
library(markdown)
library(rmarkdown)
library(tidyr)
library(dplyr)
library(ggplot2)
```
```{r}
# limit data to car name that is currently specified by the loop
cars <- mtcars[rownames(mtcars)==car,]
# create example data for each car
x <- sample(1:10, 1)
cars <- do.call("rbind", replicate(x, cars, simplify = FALSE))
# create hypotheical lat and lon for each row in cars
cars$lat <- sapply(rownames(cars), function(x) round(runif(1, 30, 46), 3))
cars$lon <- sapply(rownames(cars), function(x) round(runif(1, -115, -80),3))
cars
```
Today is `r Sys.Date()`.
```{r}
# data table of cars sold
table <- xtable(cars[,c(1:2, 12:13)])
print(table, type="latex", comment = FALSE)
```
This works fine. So I also looked at memory pressure while running my actual loop over the Rmd. which gets very high.
Is there a way to reduce memory when looping over a render call to an Rmd. file?
Is there a better way to create a report for multiple grouping factors than looping over a render call to an Rmd. file, which doesn't rely on the entire loop being inside one code chunk?
Found a solution here rmarkdown::render() in a loop - cannot allocate vector of size
knitr::knit_meta(class=NULL, clean = TRUE)
use this line before the render line and it seems to work
I am dealing with the same issue now and it's very perplexing. I tried to create some simple MWEs but they loop successfully on occasion. So far, I've tried
Checking the garbage collection between iterations of rmarkdown::render. (They don't reveal any special accumulations.)
Removing all inessential objects
Deleting any cached files manually
Here is my question:
How can we debug hangs? Should we set up special log files to understand what's going wrong?

Eval LaTeX code in R chunk (Knitr)

I'm actually creating a shiny app. In that app, there is a download button which download a PDF file that depends of user's input.
So I use a .rnw file to do generate that PDF document. I just want to do a table (with tabular) which have a number of row that depends of app user's input.
So in my R chunck, i'd like to do something like that :
\begin{tabular}{c|c}
<<echo=FALSE>>=
for (index in 1:nrow(myData))
{
SomethingThatRunLaTeXCode(paste0("\hline ",
"\Sexpr{",myData[index,1],"}"," % ","\Sexpr{",myData[index,2],"}"))
}
\hline
\end{tabular}
#
As suggested by sebastian-c, a much better way to make such a table is to use the xtable package together with Knitr. To make the Knitr chunks understand TeX, use the chunk option results='asis'.
Since your data is a data.frame, it is straight-forward:
<<echo = FALSE, results = "asis">>=
## test data
set.seed(1)
df <- data.frame(Gaussian = rnorm(10), Exponential = rexp(10))
library(xtable)
cap = paste("My caption can span multiple lines and",
"can be arbitrarily long.")
xtable(df,caption = cap)
#
For full customization, use the function print.xtable on your xtable object.
<<echo = FALSE, results = "asis">>=
print.xtable(xtable(df),table.placement = "")
#

R Knitr PDF: Is there a posssibility to automatically save PDF reports (generated from .Rmd) through a loop?

I would like to create a loop, which allows me to automatically save PDF reports, which were generated from a .Rmd file. For instance, if a variable "ID" has 10 rows, I would like R to automatically save me 10 reports, into a specific directory. These reports shall vary based on the ID selected.
A previous post (Using loops with knitr to produce multiple pdf reports... need a little help to get me over the hump) has dealt with the creation of multiple pdf reports generated from .Rnw files. I tried to apply the approach as follows:
#Data
```{r, include=FALSE}
set.seed(500)
Score <- rnorm(40, 100, 15)
Criteria1<-rnorm(40, 10, 5)
Criteria2<-rnorm(40, 20, 5)
ID <- sample(1:1000,8,replace=T)
df <- data.frame(ID,Score,Criteria1,Criteria2)
#instead of manually choosing the ID:
subgroup<- subset(df, ID==1)
# I would like to subset the Data through a loop. My approach was like like this:
for (id in unique(df$ID)){
subgroup<- df[df$ID == id,]}
```
```{r, echo=FALSE}
#Report Analysis
summary(subgroup)
```
#Here will be some text about the summary.
# At the end the goal is to produce automatic pdf reports with the ID name as a filename:
library("rmarkdown")
render("Automated_Report.rmd",output_file = paste('report.', id, '.pdf', sep=''))
Adapting your example:
You need one .rmd "template" file. It could be something like this, save it as template.rmd.
This is a subgroup report.
```{r, echo=FALSE}
#Report Analysis
summary(subgroup)
```
Then, you need an R script that will load the data you want, loop through the data subsets, and for each subset
Define the subgroup object used inside the template
render the template to the desired output
So, in this separate script:
# load data
set.seed(500)
Score <- rnorm(40, 100, 15)
Criteria1<-rnorm(40, 10, 5)
Criteria2<-rnorm(40, 20, 5)
ID <- sample(1:1000,8,replace=T)
df <- data.frame(ID,Score,Criteria1,Criteria2)
library("rmarkdown")
# in a single for loop
# 1. define subgroup
# 2. render output
for (id in unique(df$ID)){
subgroup <- df[df$ID == id,]
render("template.rmd",output_file = paste0('report.', id, '.html'))
}
This produced 8 html files in my working directory, each with a summary of a different subset of the data.
Note that this will not work if you try clicking the "knit" button inside RStudio, as that runs the R code in a separate R session. However, when you run from the console explicitly using render (or knit2pdf) the R code in the rmd file still has access to the global environment.
Rather than relying on global variables, another option would be to use parametrized reports, defining parameters in the YAML header, and passing the parameter values in as arguments to rmarkdown::render.

Resources