Save interactive Plotly in PDF or EPS in R - r

library(tidyverse)
library(easyalluvial) # https://github.com/erblast/easyalluvial
library(parcats) # https://github.com/erblast/parcats
# My data
knitr::kable(head(mtcars2))
# My Alluvial
MyAlluvial <- alluvial_wide(data = mtcars2,
max_variables = 5,
fill_by = 'first_variable')
# My Nice alluvial
p <- parcats(MyAlluvial, marginal_histograms = FALSE, data = mtcars2)
p
# Saving PDF
pdf("/Users/Master/Downloads/MyAlluvial.pdf")
p
dev.off()
I'm able to save the plot as png/jpg using RStudio GUI, but I cannot save it in a vector format (neither pdf nor eps).
As far as I known, interactive plot was generated using Plotly.
I can save printing a PDF from the browser but I don't like this!!

I was able to save your graph in a PDF file with the following code :
library(rmarkdown)
library(pagedown)
vector_RMD_Content <- c(
'---',
'title: "Untitled"',
'output: html_document',
'---',
'```{r setup, include=FALSE}',
'knitr::opts_chunk$set(echo = TRUE)',
'```',
'```{r cars}',
'library(tidyverse)',
'library(easyalluvial)',
'library(parcats)',
"MyAlluvial <- alluvial_wide(data = mtcars2, max_variables = 5, fill_by = 'first_variable')",
'p <- parcats(MyAlluvial, marginal_histograms = FALSE, data = mtcars2)',
'p',
'```')
zzfil <- tempfile(fileext = ".Rmd")
writeLines(text = vector_RMD_Content, con = zzfil)
render(input = zzfil,
output_file = "C:/stackoverflow.html")
chrome_print("C:/stackoverflow.html",
output = "C:/testpdf2.pdf")
A html file with your graph is generated with Rmarkdown. After, the HTML file is printed to PDF with the R function chrome_print of the R package pagedown.

Related

Function in my package to create an R markdown document fails with certain working directories -- Can I hack around this?

I've written a function inside a package that will take some data the user provides and make a pretty little Word document with a graph of those data. However, while the function works great when the working directory is a local drive, it fails when the drive is anything else. The errors are:
Quitting from lines 6-9 (skeleton.Rmd) Error in png(..., res = dpi,
units = "in") : unable to start png() device In addition: Warning
messages: 1: In dir.create(dirname(name), recursive = TRUE) : cannot
create dir '\myemployer.com\data\sites', reason 'Permission denied'
2: In png(..., res = dpi, units = "in") : unable to open file
'\myemployer.com\data\sites\myworkingdirectory/figure-docx/myplot-1.png'
for writing 3: In png(..., res = dpi, units = "in") : opening device
failed
I do have permission to write to my current working directory in general. In fact, when I call on a similar function in the same package that makes a table instead of a graph, it works fine.
I think what's going on is that Rmarkdown or knitr needs to temporarily save a png file of the graph in order to place it in the Word file, and it's saving it somewhere it doesn't have permission to do so. Can I get around this behavior by specifying something with rmarkdown::render?
I don't know how exactly to make a reproducible example when I'm referring to multiple files and the file structure of my package, but here's my best attempt at what info is needed. Here's the an example of the function:
myFun <- function(mydata, filename){
G <- ggplot2::ggplot(mydata, ggplot2::aes(x = A, y = B)) +
ggplot2::geom_point()
OutPath <- dirname(filename)
FileName <- basename(filename)
rmarkdown::render(system.file("rmarkdown/templates/myplot/skeleton/skeleton.Rmd",
package="mypackage"), output_dir = OutPath,
output_file = FileName, quiet = TRUE)
}
The file structure to get to skeleton.Rmd from the top level of my package:
mypackage/inst/rmarkdown/templates/myplot/skeleton/skeleton.Rmd
The actual R markdown document is something like this:
---
title: "My Plot"
output: word_document
---
```{r}
G
```
and the error message "Quitting from lines 6-9" refers to the chunk where G is outputted.
To call on this, you would use:
myFun(mydata = data.frame(A = 1:10, B = 1:10),
filename = "my file.docx")
and, if it's working, you'd get a Word file in the current working directory called "my file.docx" that contains a graph.
Is there some way to work around rmarkdown's need to temporarily save this png file? Can I set the directory for this temporary file to something else where it would have write permissions?
A possible workaround would be to render the Markdown in a temporary directory, and to copy the generated file to its destination, see:
myFun <- function(mydata, filename){
G <- ggplot2::ggplot(mydata, ggplot2::aes(x = A, y = B)) +
ggplot2::geom_point()
tmpdir <- tempdir()
on.exit(unlink(tmpdir))
OutPath <- dirname(filename)
FileName <- basename(filename)
rmarkdown::render(system.file("rmarkdown/templates/myplot/skeleton/skeleton.Rmd",
package="mypackage"), output_dir = tmpdir,
output_file = FileName, quiet = TRUE)
file.copy(file.path(tmpdir,FileName,OutPath, overwrite = T))
}
Following on from the comments, this may help. You could make the plot within the rmd file:
---
title: "Untitled"
date: "6/27/2022"
output: html_document
params:
input_df: NULL
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
mydata_rmarkdown <- params$input_df
```
## plot
```{r pressure, echo = FALSE}
G <- ggplot2::ggplot(mydata_rmarkdown, ggplot2::aes(x = A, y = B)) +
ggplot2::geom_point()
G
```
And alter you function to something like:
myFun <- function(mydata, filename){
OutPath <- dirname(filename)
FileName <- basename(filename)
rmarkdown::render(system.file("rmarkdown/templates/myplot/skeleton/skeleton.Rmd",
package = "mypackage"), output_dir = OutPath,
params = list(input_df = mydata)
output_file = FileName, quiet = TRUE)
}
Calling the function:
df1 <- data.frame(A = 1:10, B = 1:10)
df2 <- data.frame(A = 10:20, B = 10:20)
myFun(mydata = df1, filename = "my file.docx")
myFun(mydata = df2, filename = "my file.docx")
Its pretty limited in its current form as you would need df1 and df2 to have the same variable names etc. but may help you along.

R officer powerpoint complains with external image that is a pdf

I want to add a graphic in the form of a pdf to a power point file created by officer. The following code works, in the sense that the powerpoint is created and the pdf is included. But to get to the powerpoint you have to let it repair itself. Here's an example
library(officer)
library(magrittr)
my_pres <- read_pptx()
testpdf <- "test.pdf"
extImgObs_pdf <- external_img(src = testpdf)
fp_3 <- fp_text(italic = TRUE, color = "black", font.size = 14)
my_pres <- add_slide(x = my_pres, layout = 'Title Only', master = 'Office Theme')
titleTextObserved <- "some text for the title field"
my_pres <- ph_with( x = my_pres, value = fpar(ftext(titleTextObserved, fp_3)), location = ph_location_type(type = "title") )
my_pres <- ph_with( x = my_pres, value = extImgObs_pdf, location = ph_location(left = 0, top = 1.2) )
print(my_pres, target = "presentations/cmip6/chillHours_Ensemble.pptx") %>% browseURL()
With some arbitrary test.pdf file (I've generated it with the pdf driver in R and removed whitespace with the linux pdfcrop program), the above code generates a powerpoint. If you click the Repair ok message the powerpoint shows up as expected. But when you click Cancel rather than Repair, Powerpoint returns "Sorry, PowerPoint can't read ^O." Is there any way to remove the Repair message other than by manually clicking Repair?
Clicking repair makes the pdf image visible locally but the ppt doesn't show the graphic for others. Need to use something other than pdf for the graphics. png, tiff, bmp and jpeg are options.

Highlight individual bar in ggplot2 bar chart that corresponds to an individual's specific PDF report

Apologies for the bad title, I wasn't sure how to best convey what my problem is.
To give some context, I want to create a personalized scorecard for each provider in our organization using Rmarkdown. I already figured out how to create an individual PDF for each provider ; however, I want to have a simple bar chart on everyone's report with the provider's position highlighted so that they can compare themselves to their peers. Below is what I have so far:
First I created the dataset:
############################## Create dataset and export #####################################
df = data.frame(
"Provider" = c("A","B","C","D"),
"Measure" = c(1.2,0.8,1.7,0.4)
)
write.csv(df, "pathway/df.csv")
Next I created an Rmarkdown file named "TEST" that calls in the dataset and includes a graph
###################### Create Rmarkdown file named "TEST" ####################################
---
output: pdf_document
---
```{r echo=FALSE}
df <- read.csv("pathway/df.csv", stringsAsFactors = FALSE)
name <- df$Provider[i]
Dear `r name`,
This is your personalized scorecard.
```{r}
ggplot() +
geom_bar(data=df, aes(x=reorder(Provider, -Measure), y=Measure,
fill = factor(ifelse(Provider == "A", "You","Your Peers"))),
stat = "identity") +
scale_fill_manual(name = "Provider", values=c("steelblue","lightgrey"))
Finally I created an R file with the for-loop to create as many PDFs as there are providers
################ Run R file with loop to make separate PDFs per Provider #####################
library(knitr)
library(rmarkdown)
#Read data
df <- read.csv("pathway/df.csv", stringsAsFactors = FALSE)
#Create loop
for (i in 1:nrow(df)){
rmarkdown::render(input = "pathway/TEST.Rmd",
output_format = "pdf_document",
output_file = paste("handout_", i, ".pdf", sep=''),
output_dir = "pathway/folder/")
}
In the code above for the ggplot2 graph I manually coded provider "A" to be highlighted in blue and the rest of the providers grey, but we have over 30 providers and I don't want to manually code for each one. If there is some way for Rmarkdown to automatically highlight each provider in blue and the rest grey for each of their PDF reports that would be amazing. Any help is much appreciated!
There were some errors in your code, so I give the correct files here.
The RMD file:
you have to submit parameters, in your case i. You also did this in name <- df$Provider[i] but i was not given. Also you have to load ggplot2 and set your chunks ob the right positions.
---
output: pdf_document
params:
i: 1
---
```{r echo=FALSE}
library(ggplot2)
df <- read.csv("df.csv", stringsAsFactors = FALSE)
name <- df$Provider[i]
```
Dear `r name`,
This is your personalized scorecard.
```{r}
ggplot() +
geom_bar(data=df, aes(x=reorder(Provider, -Measure), y=Measure,
fill = factor(ifelse(Provider == df$Provider[i], "You","Your Peers"))),
stat = "identity") +
scale_fill_manual(name = "Provider", values=c("steelblue","lightgrey"))
```
The R file loop
Here you also have to submit the parameter too.
library(knitr)
library(rmarkdown)
#Read data
df <- read.csv("pathway/df.csv", stringsAsFactors = FALSE)
#Create loop
for (i in 1:nrow(df)){
rmarkdown::render(input = "pathway/TEST.Rmd",
output_format = "pdf_document",
output_file = paste("handout_", i, ".pdf", sep=''),
output_dir = "pathway/folder/",
params = list(i = i)))}

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.

Rmarkdown with runtime shiny can't plot rCharts plots

I have created a Rmarkdown document with shiny runtime. The reason is that depending on some selections, the data is fetched from a database and the output (tables and plots) are updated accordingly to the new selections. For the plots I was using ggplot2 and this is working fine, but I wanted to introduce more interaction using rCharts, and here is where I'm stuck, having tried a variety of combinations using renderPlot(), renderChart() and renderChart2() returning the rCharts object p, using p$show() or p$print() with different parameters, none of the options working for me.
These are code samples I'm using.
Header:
---
title: "my title"
runtime: shiny
output:
html_document
ext_widgets: {rCharts: [libraries/nvd3]}
---
Here is the plotting code
```{r, echo=FALSE, comment = NA, results = "asis", comment = NA, tidy = F}
renderPlot({
data.dt <- data.table(analysisData())
aggdata2 <- as.data.frame(data.dt[, lapply(.SD, sum), by = date])
aggdata2 <- aggdata2[with(aggdata2,order(date)),]
p <- nPlot(y ~ date, data = aggdata2, type = "lineChart", width = 600)
p$xAxis(
tickFormat = "#!
function(d) {return d3.time.format('%Y-%m-%d')(new Date(d*1000*3600*24));}
!#"
)
#p$print()
#p$show('iframesrc', cdn =TRUE, include_assets=TRUE)
return(p)
})
```
Which is indeed the best solution I have found so far: it is opening a new window with the chart that I want to create. However, it leaves a blank space in the markdown html where I want the chart to be.
For the analysisData() function here is a simplified code
```{r, echo=FALSE}
analysisData <- reactive({
variable1 = input$variable1
variable2 = input$variable2
tables = "sqlTable"
drv <- dbDriver("PostgreSQL")
dbname <- "dbname"; dbuser <- "dbuser";
dbport = dbport
dbhost <- "dbhost.com";
con <- dbConnect(drv, host=dbhost, port = dbport, dbname=dbname, user=dbuser)
selectStatement = "select * from %s where variable1=%s and variable2=%s"
query = sprintf(selectStatement, tables, variable1, variable2)
dataset <- dbGetQuery(con,query)
lapply(dbListConnections(drv),dbDisconnect)
dbUnloadDriver(drv)
dataset$date <- as.Date(dataset$date)
dataset
})
```
Do you have any suggestions on how can I solve the problem? Any hint is appreciated.

Resources