I'm getting the following error when using the officer function ph_with_vg_at:
Error in dml_pptx(file = dml_file, width = width, height = height, offx = left, :
argument "height" is missing, with no default
I think the issue is the "funWorkaround" wrapper that I'm using in place of ph_with_vg_at. This function ensures that certain characters are encoded properly when writing to PPT (stole this function here). I don't get the error when I use ph_with_vg_at instead of funWorkaround.
This was all working perfectly until today, when I updated all of my packages. So not sure if this is an officer/rvg issue or maybe a piping issue. Or none of the above!
I'm looking to either resolve this error or find another way to preserve character encoding when writing from R to PPT. Thanks!
funWorkaround <- function(x, code, left, top, height, width, ...) {
# Re-Store old encoding on end
sOldEnc <- getOption("encoding")
on.exit(options(encoding=sOldEnc))
# Modify encoding
options(encoding="UTF-8")
# Create plot
return(ph_with_vg_at(x, code, left, top, height, width, ...))
}
ppt_test <- ppt_test %>%
add_slide(layout = "Two Content", master = "Office Theme") %>%
ph_with_text(type = "title", str = "Satisfaction with Issue Details") %>%
funWorkaround(code = print(issuedetails.plot),
left = 0.46,
top = 2,
width = 11.8,
height = 4.71)
Solved this by going back to using the straight ph_with_vg_at function instead of the funWorkaround wrapper. To make sure I get the right connection encoding, I put the following at the start of my deck creation script:
oldEnc = getOption("encoding")
options(encoding = "UTF-8")
Then I put this at the end of the script:
options(encoding = oldEnc)
This moves the connection settings to UTF-8 while building the PPT but then ensures that it returns to original native.enc once the PPT file is built. Otherwise, you might run into unforeseen issues (like reading data) if the setting remains in UTF-8.
Are you using a later version of the rvg package? There's a new argument ggobj which is the 3rd argument by default. If you simply name the arguments in your workaround, it should work:
funWorkaround <- function(x, code, left, top, height, width, ...) {
# Re-Store old encoding on end
sOldEnc <- getOption("encoding")
on.exit(options(encoding=sOldEnc))
# Modify encoding
options(encoding="UTF-8")
# Create plot
return(ph_with_vg_at(x, code=code, left=left, top=top, height=height, width=width, ...))
}
Related
I have a large dataframe that I presented as a formattable object. When the object renders in the R Studio viewer, I have a scrollbar to move up and down. But when I export the image it does not export the whole table, just a part of it. How can I export the whole table as an image?
Here is my code for the formattable object:
formattable(por.pais,align =c("c","c","c","c"),
list('Equipo' = formatter("span", style = ~ style(color = "grey",font.weight ="bold")), 'Eficiencia'= color_tile(customRed, customGreen)))
And here is how R is exporting the image:
formattable object
Yes, in Viewer, Export, you can get a maximum of 1820 pixels wide and 796 pixels high. If you increase the pixels and click update preview this will help with medium sized tables that are within this size, but does not help if your table is bigger (like mine).
Ok so I found this code and it works to perfection:
First, install the formattable, htmltools and webshot packages:
install.packages("htmltools")
install.packages("webshot")
install.packages("formattable")
Now load them:
#Load the following libraries:
library("htmltools")
library("webshot")
Run the following function:
export_formattable <- function(f, file, width = "100%", height = NULL,
background = "white", delay = 0.2)
{
w <- as.htmlwidget(f, width = width, height = height)
path <- html_print(w, background = background, viewer = NULL)
url <- paste0("file:///", gsub("\\\\", "/", normalizePath(path)))
webshot(url,
file = file,
selector = ".formattable_widget",
delay = delay)
}
Now, create a formattable object:
tb <- formattable(dataframe)
Fianlly, save your table as an image:
export_formattable(tb,"my_table.png")
Note: You can also use the .jpg extension.
Whenever I use ggplot2 I get following the same error
x2012 <- data.frame(readRDS(file = "Exercises05/x2012_1_6cleaned10.Rda"))
i <- 1
while (i<=250){
x2012[[i,1]] <- mean(sample(nrow(x2012), 25, replace = FALSE))
i = i+1
}
mean(x2012$sumtotprice)
sd(x2012$sumtotprice)
library("tidyverse")
ggplot(x2012, aes(sumtotprice)) +
geom_density()
Error in (function (filename = "Rplot%03d.png", width = 480, height =
480, : unable to start png()
The dataset is irrelevant, I always get this error.
Thank you for your time, and apologies for not providing a more general example!
I believe this is related to path length limits in Windows. When rendering outputs 'inline' in the RMD it seems it occurs via a tmp directory that throws an error because its parent path is too long. However, if you just change the options so that the output is in the console rather than inline by adding
editor_options:
chunk_output_type: console
at the top of the document it seems to fix it for me. This can also be accomplished in the menu that drops down from the gear icon at the top of the source pane in RStudio.
Thanks for the response,
In the thread (stackoverflow.com/q/45113597) posted by r2evans, I found following solution:
Saving the markdown as a new file will fix the problem temporarily, however, I do not know of a long term solution.
I'm running some plot code in markdown to generate a plot in a xaringan presentation. The code works but is a little long and so takes up the whole presentation slide forcing the actual plot off the edge (see img).
How can I hide the code block generating the plot?
Also how can I compress the code block with a scroll bar?
```{r}
r_exp.fun <- function(r = 0.05, N_pop = 10, t = 150)
{
N <- vector("numeric", length = t)
N[1] <- N_pop
for (i in 2:t)
{
N[i] <- N[i-1] + (N[i-1] * r)
}
return(N)
}
args_list <- list(0.045, 0.055, 0.06)
matplot(
mapply(
r_exp.fun,
r = args_list
)
,type = "l")
abline(h = list(7052, 29150, 59000))
```
The alternative is of course to save as an image but if possible I would prefer to be able keep the code as a resource for anyone with the link.
Thanks!
As alistaire already mentioned in the comments, RMarkdown has various chunk options to customize the output.
For your problem the option echo needs to be set to FALSE.
The other options (from https://rmarkdown.rstudio.com/lesson-3.html):
include = FALSE
prevents code and results from appearing in the finished file. R Markdown still runs the code in the chunk, and the results can be used by other chunks.
echo = FALSE
prevents code, but not the results from appearing in the finished file. This is a useful way to embed figures.
message = FALSE
prevents messages that are generated by code from appearing in the finished file.
warning = FALSE
prevents warnings that are generated by code from appearing in the finished.
fig.cap = "..."
adds a caption to graphical results.
I'm trying to add an image to a datatable in R form the DT package. I fount this question: How to embed an image in a cell a table using DT, R and Shiny and it works for the image that's online. But when I tried to add a image that i have locally (created with R) it just doesn't come up. This is an example of my problem:
x = rnorm(1000)
png(paste0("Graficas/test.png"))
Plot = plot(x, type = "l")
dev.off()
camino = '<img src="Graficas/test.png" height="30"></img>'
data = data.frame(0.5,camino)
datatable(data, escape = FALSE)
the output is
and I can't understand why its happening
This is one way to do it (by embedding base64 encoded images and using that for the src).
First we'll make a small helper:
img_uri <- function(x) { sprintf('<img src="%s"/>', knitr::image_uri(x)) }
That will let us make a data uri. We're slurping up the whole file and converting it to base64 then doing a bit more formatting before sticking the entire blob into the src attribute.
This is what a 1x1 pixel PNG looks like encoded that way:
<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=\"/>
So, we just do the same with the one you created:
x = rnorm(1000)
png(paste0("test.png"))
Plot = plot(x, type = "l")
dev.off()
camino = img_uri("test.png")
data = data.frame(0.5 ,camino)
DT::datatable(data, escape = FALSE)
Yours is having an issue b/c it's not "URI" and it has no way of pulling from the local system. It might work in a browser context with a file://… URL.
So I'm trying to write an html R markdown document with interactive shiny bits that allow the user to edit a graph and then download the results to a pdf. However, there is something catastrophically wrong with the way that I'm trying to do this because as soon as the html starts, it overwrites the original markdown file with the contents of the pdf - turning it into complete gibberish right in the editor.
I doubt that I've found a completely new way to fail at R but I haven't been able to find where anybody else has had this issue. Additionally, I've looked over the shiny reference material and I'm just going in circles at this point, so any help would be greatly appreciated.
I'm using Rstudio 1.0.44, rmarkdown 1.2 and shiny 0.14.2. A small (not)working example:
---
title: "Minimum Failing Example"
author: "wittyalias"
date: "December 5, 2016"
output: html_document
runtime: shiny
---
```{r echo = FALSE}
library(ggplot2)
today <- Sys.Date()
inputPanel(downloadButton("dnld", label = "Download pdf"))
renderPlot({
# Example code from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/
p1 <<- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
geom_line() +
ggtitle("Growth curve for individual chicks")
p1
})
reactive({
fname <- paste0("Chick Weight - ", today, ".pdf")
output$dnld <- downloadHandler(filename = fname,
content = makethepdf(file))
makethepdf <- function(fname) {
pdf(fname,
width = 14,
height = 8.5)
p1
dev.off()
}
})
```
EDIT: To be clear: I want the user to be able to download multiple pages of graphs, some of which will have different formatting. The user won't be downloading just a pdf version of the markdown document.
This happens because reasons I weren't able to identify makethepdf runs with the file = [name of the file]. Insert a print(fname) to see. The download handler isn't supposed to be inside an observer though. You need to have it outside on its own. I also failed to make pdf() dev.off() combination work for some reason so here's a working version below.
output$dnld = downloadHandler(filename = paste0("Chick Weight - ", today, ".pdf"),
content = function(file){
ggsave(file, plot = p1, width = 14, height = 8.5)
})
Use tempfile() and tempdir() to create a temporary file:
output$downloadReport = downloadHandler(
filename = function() {
normalizePath(tempfile("report_", fileext = ".docx"), winslash = "/")
},
content = function(file) {
out = rmarkdown::render("./report.Rmd",
output_file = file,
output_dir = tempdir(),
output_format = "pdf_document",
intermediates_dir = tempdir(),
envir = new.env(),
params = list( fontSize = 10)
)
})
I usually use a separate .Rmd template for my downloaded reports as the layout and text are usually similar but not identical to what works in an app.
I also find using parameters is a convenient way to pass input settings from my app to my report. See this RStudio post for details
Alright, so there are a number of problems with my code, but using some of the suggestions in the other answers I've been able to work it out.
The primary problem with this little document is that content in the downloadHandler is a function, but in my code I set content equal to the result of a function call. It looks like when the shiny app is first run it compiles content, thinking that it is a function, but actually ends up calling the function. It sends file as an arguement, which doesn't seem to exist except as a base function. Calling makethepdf with just file throws an error when I use it in the console, but for whatever reason in this app it just goes with the call, apparently with file = [name of the .Rmd] (just as OganM said).
To fix, change this:
output$dnld <- downloadHandler(filename = fname,
content = makethepdf(file))
to
output$dnld <- downloadHandler(filename = fname,
content = makethepdf)
To be clear: this code does not overwrite the .Rmd file if content calls makethepdf with any argument other than file. For instance, content = makethepdf(fnm)) causes the download button to display an object not found error and content = makethepdf(fname)) causes the download button to throw an attempt to apply non-function error when pressed.