I would like to include screenshots from an observable notebook in an rmarkdown rendered to pdf. Directly including code blocks that call robservable does not work, so I thought I could use the webshot package instead. The example below creates a file, test.html, that does contain the interactive notebook. However, the rendered pdf still does not show any screenshot.
---
title: "robservable and webshot"
output: pdf_document
---
```{r}
knitr::opts_chunk$set(screenshot.opts = list(delay = 5))
library("robservable")
library("webshot")
library("htmlwidgets")
library("dplyr")
```
This is a test.
```{r}
f <- "test.html"
robservable("#d3/horizontal-bar-chart", include = "chart") %>%
saveWidget(f)
```
```{r}
webshot(f)
```
Related
I have two RMarkdown files. main.Rmd which is the main file which is rendered as well as example.Rmd which holds a longer example and is used elsewhere (hence it lives in its own document).
I want to include example.Rmd in the main.Rmd file with code highlighting of its RMarkdown code but the code of example.Rmd does not need to be executed, as if I set eval=FALSE and copied all code into the chunk by hand.
An example MWE is
main.Rmd
---
title: This is main.rmd
output: html_document
---
```{r}
# attempt that doesnt work
cat(readLines("example.Rmd"), sep = "\n")
```
and in example.Rmd
---
title: This is example.rmd
output: html_document
---
```{r}
# code that is not executed but shown in main.Rmd
data <- ...
```
Set eval=FALSE in the example.Rmd file and then include it in main.Rmd using child chunk option.
example.Rmd
---
title: This is example.Rmd
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(eval = FALSE)
```
```{r}
# This is from example.Rmd
x <- rnorm(10)
y <- rnorm(10)
lm(y ~ x)
```
```{r}
# some comments
print("This is from example.Rmd")
```
main.Rmd
---
title: This is main.Rmd
output:
html_document:
highlight: haddock
---
```{r example, child="example.Rmd"}
```
Edit
To show full source-code of the Rmarkdown file, one possible option could be reading that Rmd file and then cat it with chunk option comment="".
Now about the syntax highlighting; there's a chunk option class.output with which it is possible to specify a language name for which pandoc supports syntax highlighting.
You can get the list of language names for which pandoc has syntax highlighting support by running the following,
pandoc --list-highlight-languages
(Note, if you don't have pandoc installed separately, you can also use the pandoc installed with Rstudio itself. Run rmarkdown::pandoc_exec() to get the pandoc executable path)
Now, the file we are trying to include actually contains not just R code, but also markdown and yaml syntaxes. So it's a kind of mixed thing and pandoc has no syntax highlighting support out of the box for this. Still I have chosen c as syntax highlighting language just to show the possibility. (Also tried r, but syntax-highlighting is not so distinctive)
---
title: This is main.Rmd
output:
html_document:
highlight: tango
---
## Rmarkdown
```{r example, echo=FALSE, class.output="c", comment=""}
cat(readLines("example.Rmd"), sep = "\n")
```
But still if you want a specific syntax-highlighting for Rmarkdown, you can actually create one. See here from the pandoc documentation itself and also this answer on SO about this.
I'm maintaining R code in my company that is use by multiple colleagues. I decided to convert my code into a package to make it simpler to share, maintain and document. My package is build to stay internal, be used in a close environment and is not going to be on CRAN. I'm using Rstudio and it's going relatively well but I hit a problem when building vignettes.
The problem is that my code makes very specific, long and complex analysis on very big datasets. It's therefore not possible for me to have the vignette built every time I rebuilt the package. Even less having the user do it when using devtools::install_git(build_vignettes = TRUE). I've found a solution to this problem in this nice blog (https://ropensci.org/blog/2019/12/08/precompute-vignettes/). Briefly, you add .orig after your vignettes names .Rmd so they are not identified as vignette by the build process. Then, when you are ready, you precompile your script by knitting your .Rmd.orig file with:
knitr::knit("vignettes/longexample.Rmd.orig", output = "vignettes/longexample.Rmd")
This will create a quick and easy compilable version of your vignette for your package. This works for basic document with text and figures. However, I need to enter a leaflet map into my vignette. If I use this process to create my vignette with a leaflet, I get an error:
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## Error in path.expand(path): invalid 'path' argument
I think this is a message showing that knitr is trying to get a screenshot of my map to save it as an image. This is not what I want, I want an actual map.
Reproducible example
The vignette I wrote:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```{r setup, message=F, warning=FALSE}
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```{r}
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
## The leaflet
```{r}
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r}
m
```
Then, I compile it with :
knitr::knit("c://temp//longexample.Rmd.orig", output = "c://temp//longexample.Rmd")
which produce this output:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```r
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```r
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
```
## I've waited this long!
```
## The leaflet
```r
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r}
m
```
```
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
```
```
## Error in path.expand(path): invalid 'path' argument
```
So, it's not able to pass along the leaflet into the new knit markdown file (which makes sense).
I tried to bypass this problem by saving the leaflet into a temporary file like this (in my .orig file):
```{r, include=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
This would save my map, but then I have to find a way to add the next code block in the compiled version, so it appears and it's run only there. Some way to have the code block below passed as-is by knitr.
```{r, include=FALSE}
m <- readRDS("c://temp/temp_leaflet.rds")
```
So I'm stuck. Any idea how to display a leaflet into a markdown/vignette after a precompilation?
This problem can be fix by having knitr knit "asis" the lines of code you want to knit in the second run, so when building the vignette... To do this, you can change the section:
```{r}
m
```
by:
```{r, echo=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=FALSE, warning=FALSE} \n")
cat("library(leaflet) \n")
cat("m <- readRDS('c://temp/temp_leaflet.rds') \n")
cat("```")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=TRUE} \n")
cat("m \n")
cat("```")
```
Explanation
First, you save your map (or data) somewhere in an rds file. Then, you use the results="asis" code block option and the cat function to write the code block that you need rendered only the in the second compilation (when the vignettes are build). So you are actually wrapping Rmarkdown code into Rmarkdown... It's ugly and confusing, but it works. Using this approach, the render code after knitting the Rmd.orig file looks like normal Rmarkdown code:
```{r, echo=FALSE, warning=FALSE}
library(leaflet)
m <- readRDS('c://temp/temp_leaflet.rds')
```
```{r, echo=TRUE}
m
```
It will then be perfectly render in your vignettes.
The only complication now is to manage the save and read location of the rds file because markdown and vignettes can have tricky working directories.
So the final .orig file is now:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```{r setup, message=F, warning=FALSE}
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```{r}
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
## The leaflet
```{r}
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r, echo=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=FALSE, warning=FALSE} \n")
cat("library(leaflet) \n")
cat("m <- readRDS('c://temp/temp_leaflet.rds') \n")
cat("```")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=TRUE} \n")
cat("m \n")
cat("```")
```
I am attempting to use R Markdown Notebooks (.Rmd files) in R Studio to capture notes and excercises while learning R programming. I find that any plots generated through the code chunks are being replicated in the corresponding html file correctly, however I am unable to get images to be replicated in the html.
Sample code below -
The image is a .PNG file in the working directory path.
```{r}
library(knitr)
knitr::include_graphics("MyImage.PNG")
```
This replicates the image in the R Markdown Notebook correctly, but not in the html file.
I am able to replicate the image in the html file by directly using html syntax -
<img src="MyImage.PNG" alt="MyImage">
I have looked through other questions around this topic, but could not resolve this issue through any of the solutions provided. I would be grateful if any of you can help resolve this.
Thanks!
I think this might be a bug to do with adding shiny.
I just did a quick test and it works for a normal document:
---
title: "Test"
output: html_document
---
```{r setup, include=FALSE}
library(knitr)
opts_chunk$set(echo = TRUE)
```
```{r, echo=FALSE, out.width="50%"}
include_graphics("../images/RMarkdownOutputFormats.png")
```
but when I add shiny it doesn't work anymore:
---
title: "Test"
output: html_document
runtime: shiny
---
```{r setup, include=FALSE}
library(knitr)
opts_chunk$set(echo = TRUE)
```
```{r, echo=FALSE, out.width="50%"}
include_graphics("../images/RMarkdownOutputFormats.png")
```
I had the same problem when using shiny_prerendered with a learnr tutorial... This from Yan Holtz worked for me:
library(png)
library(grid)
img <- readPNG("photos/header_stats.png")
grid.raster(img)
I have a shiny app (radiant.data) that uses knitr to generate reports viewable inside the application (R > Report). Because the output is displayed inside a shiny app I need a render function for something like a DT table to be displayed (i.e., convert to shiny.render.function). This all works fine.
Now, however, I want to use a custom print method to handle rendering so I can just use DT::datatable(mtcars) with knitr and knit_print.datatables to generate a shiny.render.function.
Below some example R-markdown that includes the knit_print.datatables function i'm using. chunk1 and chunk2 show a shiny.render.function as intended but the chunk6 shows nothing. If screenshot.force = TRUE I get a screenshot from chunk6 but that is not what I want either.
Example R-markdown to be processed with knitr::knit2html
```{r chunk1}
knitr::opts_chunk$set(screenshot.force = FALSE)
DT::renderDataTable(DT::datatable(mtcars))
```
```{r chunk2}
knit_print.datatables <- function(object, ...) {
DT::renderDataTable(object)
}
```
```{r chunk3}
knit_print <- knitr::knit_print
knit_print.datatables(DT::datatable(mtcars))
```
```{r chunk4}
getS3method("knit_print", "datatables")
```
```{r chunk5}
class(DT::datatable(mtcars))
```
```{r chunk6}
DT::datatable(mtcars)
```
I realize the R-markdown above, although reproducible if you have knitr and DT installed, looks a bit weird but when I export the knit_print.datatables function properly I get the same result in my application (see example output below).
I would like to use non-standard fonts in a ggplot2 chart which I then embed in an rmarkdown document, which get knitted into a PDF. My current workflow is to specify the font in the chart, then knit, then run extrafonts::embed_fonts on the created PDF. My question is: can I specify directly in the rmarkdown document that fonts should be embedded in the outputted PDF?
Minimal example:
---
title: "Untitled"
output: beamer_presentation
---
```{r}
library(extrafont)
library(ggplot2)
loadfonts()
qplot(iris$Sepal.Length) + theme_light(base_family = "CM Roman")
```
knitr::knit2pdf("test.rmd")
embed_fonts("test.pdf")
If you set the graphics device to "cairo_pdf" the fonts will be embedded. You can do this for individual chunks or for the whole document using knitr::opts_chunk$set
I used a really obviously different font below so that it was clear the fonts were really being set.
The package is called "extrafont" not "extrafonts"
---
title: "Untitled"
output: beamer_presentation
---
```{r, echo=FALSE, message = FALSE}
knitr::opts_chunk$set(warning=FALSE, message=FALSE, echo = FALSE, dev = "cairo_pdf")
```
```{r}
library(extrafont)
library(ggplot2)
loadfonts()
```
##
```{r, fig.width = 5}
qplot(iris$Sepal.Length) + theme_light(base_family = "Vladimir Script")
```