kableExtra HTML styling in Rmarkdown and kable_save() - r

This has plagued me for too long, I would appreciate help. I have been investing time into kable, but it hasn't quite worked out for me the way I would like. I am looking to create multi grouped rows as in the image
The code to do this is as follows:
collapse_rows_dt <- expand.grid( District = sprintf('District %s', c('1', '2')), City = sprintf('City %s', c('1', '2')), State = sprintf('State %s', c('a', 'b')), Country = sprintf('Country with a long name %s', c('A', 'B'))
)
collapse_rows_dt <- collapse_rows_dt[c("Country", "State", "City", "District")]
collapse_rows_dt$C1 = rnorm(nrow(collapse_rows_dt))
collapse_rows_dt$C2 = rnorm(nrow(collapse_rows_dt))
kbl(collapse_rows_dt, booktabs = T, align = "c", linesep = '') %>%
collapse_rows(1:3, row_group_label_position = 'stack')
The problem is that when I run this in R markdown I get the HTML version in the output (see below)
This obviously is not good enough. I CAN get the correct output (first image) if I knit to pdf, but that's it. If I try doing save_kable() it turns out in the HTML format as in the second image. Kniting to pdf every time is so impractical that I can't possible use kable anymore if I can't fix this. That is a big deal for me.
If I set format='latex' then nothing shows up inline and when I try to kable_save() I get this error message:
this is Xtex version 3....(tex live 2020/w32Tex) preloaded format=xlatex) restricted \write18 enabled.
Entering extended mode
Followed by a pop that informs me (R crashes)
R session aborted, r encoutered a fatal error
All HTML tables that don't require latex show up inline appropriately and will save as their actual image.
Relevant Up to Date Packages:
- library(webshot)
library(tinytex) (also tried without)
library(magick)
library(plyr)
library(tidyverse)
library(dplyr)
library(knitr)
library(skimr)
library(kableExtra)
Also:
Ghostscript 9.52 is current and set to environment
Miktext 2.9
Have Tried:
updating imageMagick via install.packages(magick
editing the policy.xls in ImageMagick to bypass a security feature ImageMagick security policy 'PDF' blocking conversion
Manually installing the following Latex packages
library(tinytex)tlmgr_install(pkgs = 'standalone')tlmgr_install(pkgs
= 'preview')tlmgr_install(pkgs = 'polyglossia')tlmgr_install(pkgs = 'xltxtra')tlmgr_install(pkgs = 'realscripts')
Setting Mixtex to environment path

If you want to knit and include the image produced via LaTeX and PDF, you can use kableExtra::as_image
---
output: html_document
---
```{r}
library(kableExtra)
library(magrittr)
collapse_rows_dt <- expand.grid( District = sprintf('District %s', c('1', '2')), City = sprintf('City %s', c('1', '2')), State = sprintf('State %s', c('a', 'b')), Country = sprintf('Country with a long name %s', c('A', 'B'))
)
collapse_rows_dt <- collapse_rows_dt[c("Country", "State", "City", "District")]
collapse_rows_dt$C1 = rnorm(nrow(collapse_rows_dt))
collapse_rows_dt$C2 = rnorm(nrow(collapse_rows_dt))
kbl(collapse_rows_dt, "latex", align="c", linesep="", booktabs = T) %>%
collapse_rows(1:3, row_group_label_position = 'stack') %>%
kable_styling(latex_options = c("striped", "scale_down")) %>%
as_image()
```

Related

render image from disk in R markdown / Dashboard on user selection dropdown

I have a folder full of charts, generated from a previous step. All of them are PNG files.
I want to be able to choose anyone using Flexdashboard and load it.
As no shiny or server service is needed I tried Crosstalk package
library(crosstalk)
library(magrittr)
library(png)
df <- list.files("plots/", full.names = TRUE) %>%
as_tibble() %>%
magrittr::set_names("path")
shared_data <- SharedData$new(df, key = ~path)
p <- shared_data %>% readPNG(source = path)
bscols( filter_select(id = "file_id",
label = "CHOOSE",
sharedData = shared_data,
group = ~path),
p)
I am stuck on a very simple error i cannot solve as all paths are properly read from file:
Error in path.expand(source) : invalid 'path' argument
Tried to use knitr too:
bscols(filter_select("path", "CHOOSE", shared_data),
knitr::include_graphics(shared_data, ~path))
Error in makeGroupOptions(sharedData, group, allLevels) : argument "group" is missing, with no default
Maybe there is a simpler approach but crosstalk seemed a very simple one as it does not need shiny or any other component but a data frame.
This can be achieved more easily by using bsselectR
The library is 5 years old but works perfectly in my trial. It does not offer the same level of in-plot interaction as crosstalk but might be sufficient for the current purpose.
Below is the code snippet to add to R Markdown document. I've altered the sample code to allow for recursive directory walk.
The plots directory needs to be placed in the same directory as the R file.
```{r}
#
library(stringr)
library(bsselectR)
state_plots <- paste0(list.files("plots", full.names = TRUE, recursive = TRUE))
names(state_plots) <- str_replace_all(state_plots,
c("\\.png" = "",
"plots/" = ""))
bsselect(state_plots, type = "img", selected = "sns_heatmap",
live_search = TRUE, show_tick = TRUE)
```
Output :

How to combine an R script and R markdown into one file?

I am making a Shiny app to keep track of some things that need to be done at work. One component of the app is to send an email letting everyone know what they are responsible for doing that week. I originally wrote the code to do that in two separate pieces, an R markdown file to generate the emails, and an R script to iterate through a table that has user's names in it to generate a personalized email that includes the tasks for which they are responsible. Locally, this works fine. I have a button setup to run the R script, which then sources the R markdown code for each user and sends an email to each user. After deploying the app this no longer works. Debugging the Shiny app has proved tricky, but I'm guessing is has to do with the fact that the R script and R markdown file are not communicating with each other. I was wondering if I could solicit some advice on how to resolve this. Thank you in advance for any insight or advice, I only program a little for work and have been struggling to fix this. The code below is a simplified version of what I'm trying to use.
#DATA
email.addresses <- data.frame(user = as.character(c("Peyton Mannning", "John Elway")),
email.address = as.character(c("Peyton.manning#gmail.com", "john.elway#gmail.com")),
stringsAsFactors=FALSE)
email.complete <- data.frame(task = as.character(c("Do the dishes", "Mop the floor")), next.completion = as.Date("2020-12-10"), Responsible.Persons = as.character(c("Peyton Manning", "John Elway")))
#R script
library(lubridate)
library(blastula)
for (user in unique(email.addresses$User)){
email <- render_email("email markdown.Rmd")
email %>%
smtp_send(
from = "personal#email.net",
to = email.addresses$Email[email.addresses$User == user],
subject = paste("Cleaning Schedule for", floor_date(Sys.Date() - 1, "weeks") + 1, sep = " ", collapse = NULL),
credentials = creds_key(id = "gmail")
)
}
# markdown
```{r, results='asis', echo = FALSE}
email.complete.user <- email.complete[email.complete$Responsible.Persons == user,]
library(kableExtra)
library(dplyr)
email.complete.user %>%
kbl(row.names = FALSE, col.names = c("Task", "Completion Deadline", "Responsible User"), format = "html", table.attr = "style='width:100%;'", longtable = TRUE) %>%
kable_styling(bootstrap_options = c("striped", "hover", position = "left"), font_size = 20) %>%
kable_minimal()```

Rendering fusionchartsR htmlwidgets in rmarkdown

I am building a new htmlwidget package called fusionchartsR (https://github.com/alexym1). I tried to embed a little piece of code to my rmarkdown report however, it doesn't work and I don't know why. I tried differents strategies without any success.
First strategy
---
title: "Stack overflow"
author: "John Doe"
date: "01/04/2020"
output: word_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Render an htmlwidget graphic
```{r}
library(fusionchartsR)
df <- data.frame(label = c("Venezuela", "Saudi", "Canada", "Russia"), value = c(290, 260,180, 115))
fusionPlot(data = df, type = 'pie2d') %>%
fusionTheme(theme = "fusion")
```
Second strategy
# Webshot and phantomjs have been previously installed.
library(webshot)
webshot::install_phantomjs()
# Then, I loaded packages and built a little piece of code
library(fusionchartsR)
library(htmlwidgets)
df <- data.frame(label = c("Venezuela", "Saudi", "Canada", "Russia"), value = c(290, 260,180, 115))
widget <- fusionPlot(data = df, type = 'pie2d') %>%
fusionTheme(theme = "fusion")
# Save a rendered widget to an HTML file
saveWidget(widget = widget, file = "Mywidget.html")
# An error appeared: `Error: pandoc document conversion failed with error 99`
# Take a webshot
webshot(url = "Mywidget.html", file = "webshot.png")
The Mywidget.html can be found on your Documents folder.
How can I solve this problem ?
I will be very greatful !
Instead of using webshot, you should consider to try webshot2 on https://github.com/rstudio/webshot2 which doesn't suffer from this issue. I have replicated your scenario with webshot2, the issue is resolved as below screenshot. See my detailed answer to the similar case.
The code:
# Webshot and phantomjs have been previously installed.
library(webshot2)
# install.packages("remotes")
# remotes::install_github("alexym1/fusionChartsR")
# Then, I loaded packages and built a little piece of code
library(fusionchartsR)
library(htmlwidgets)
df <- data.frame(label = c("Venezuela", "Saudi", "Canada", "Russia"), value = c(290, 260,180, 115))
widget <- fusionPlot(data = df, type = 'pie2d') %>%
fusionTheme(theme = "fusion")
# Save a rendered widget to an HTML file
saveWidget(widget = widget, file = "Mywidget.html")
# An error appeared: `Error: pandoc document conversion failed with error 99`
# Take a webshot
webshot(url = "Mywidget.html", file = "webshot.png")
The output:

How can I add a fontawesome icon to a table in Rmarkdown?

I'm looking for tidy way to add a hyperlink incorporating a fontawesome icon to an Rmarkdown table (kable) — for incorporation in an html bookdown page.
In other parts of my document, I've used the icon package, to render a hyperlinked fontawesome icon (outside of a table) using standard markdown syntax, e.g.:
`r icon::fa("file-pdf", size = 5)](https://www.google.com/){target="_blank"}`
But this approach doesn't work when I've attempted to incorporate it as part of a kable.
```{r}
library(icon)
library(knitr)
library(tidyverse)
## note this code throws the following error: Error in
## as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors =
## stringsAsFactors) : cannot coerce class "c("knit_asis",
## "knit_icon")" to a data.frame
link_location <- "www.google.com"
data_test_1 <- data.frame(
file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
pdf_logo = icon::fa("file-pdf")) %>%
mutate(pdf_logo = cell_spec(pdf_logo,
link = link_location)) %>%
kable("html", escape = F, align = "c")
data_test_1
```
So far I've come up with a workaround that involves downloading the .svg file from the fontawesome website and adding it as an image. It works... sort of, but I would prefer to have the ability to change the size of the icon and make it more easily reproducible.
This is the code for my current workaround.
```{r fontawesome_table ='asis'}
library(tidyverse)
library(kableExtra)
## download svg from location manually
https://fontawesome.com/icons/r-project?style=brands
data_test_2 <- data.frame(
file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
R_logo = "![](r-project-brands.svg)") %>%
mutate(R_logo = cell_spec(R_logo, link = "https://cran.r-
project.org/")) %>%
kable("html", escape = F, align = "c")
data_test_2
```
Which produces this output...
Does anyone have any ideas for how I could either, adjust the size the icon in the table, or call the icon from another package/css to create a more tidy solution?
Here is a way using the fontawesome package instead. I also had to use a custom link building function:
```{r, echo = F, message=F, warning=F}
library(fontawesome)
library(knitr)
library(tidyverse)
library(kableExtra)
## note this code throws the following error: Error in
## as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors =
## stringsAsFactors) : cannot coerce class "c("knit_asis",
## "knit_icon")" to a data.frame
link_location <- "www.google.com"
addLink <- function() {
paste0("", as.character(fa("file-pdf")), "")
}
data_test_1 <- data.frame(file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
pdf_logo = addLink())
kable(data_test_1, escape = F, align = "c")
```
Another solution is the icons package. With icons you cannot only use fontawesome but several icon packages incl. Material icons, e.g.
Install it with devtools::install_github("mitchelloharawild/icons").
Download the font you want to use, here: download_fontawesome().
Now access the icon with either fontawesome("rocket", style = "solid") or icons::fontawesome$solid$rocket.
In an Rmarkdown document like this:
```{r icon-chunk}
fontawesome("rocket", style = "solid")
```
or inline like this
`r icons::fontawesome("rocket", style = "solid")`
In some cases you may need backticks. E.g. for the R icon
fontawesome$brands$`r-project`

How to show and run code but don't print results in Rmarkdown knitr

When I knit the following code chunk in Rmarkdown it will print out the results as well. I just want to run and show the code. In other code chunks in the same .Rmd file this knitr syntax works...
```{r import, results = "hide"}
gs_ls()
df <- gs_title("worlds-view-of-America")
confInPres <- df %>% gs_read(ws = "Sheet1", range = cell_rows(1:38))
colnames(confInPres) <- paste("year", colnames(confInPres), sep = "_")
colnames(confInPres)[1] <- "Country"
confInTrump <- select(confInPres, Country, year_2017)
favUS <- df %>% gs_read(ws = "Sheet2", range = cell_rows(1:38))
```
Take a look here.
If you want to show the code, use echo=TRUE.

Resources