Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 742
shirewoman2 Avatar asked Oct 25 '25 17:10

shirewoman2


1 Answers

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))
  
}
like image 140
Waldi Avatar answered Oct 27 '25 06:10

Waldi