2

I want to add a baseplot to a word document.

In the documentation for the officer package there's an example that uses the plot_instr function:

anyplot <- plot_instr(code = {
  barplot(1:5, col = 2:6)
  })

doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = tempfile(fileext = ".docx"))

I want to add a plot to a word document inside a function so I need variable input for the plot function like this:

x=1:5
cols=2:6
anyplot <- plot_instr(code = {
    barplot(x,col=cols)
})

doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = tempfile(fileext = ".docx"))

But the code above doesn't work and I can't find any other examples of plot_instr usage.

Robert
  • 924
  • 1
  • 9
  • 20
  • 2
    I'm guessing that that "Code" runs on a difrent enviroment and thus can't access the variables defined. (I'm not sure on it though) So one approach that might work is to store those variables as a .rdata object and use the code to access the variable. that way you can grab them without referencing any variable previously defined. This is however extremely inefficient and should go as a last resort. (plus i didn't actually test for it) – dspn Oct 28 '20 at 15:43
  • The issue is about the name `x` in your code, first argument of `body_add` is also x... – David Gohel Oct 31 '20 at 16:17

2 Answers2

1

I think I found a solution!

When I set a breakpoint before the barplot(...) call, I could see the code when body_add is called with a plot_instr wrapper function. The code creates a temporary png file. I copied this code and adapted it:

x=1:5
cols=2:6

doc <- read_docx()

file <- tempfile(fileext = ".png")
options(bitmapType = "cairo")
png(filename = file, width = 5, height = 5, units = "in", res = 300)
tryCatch({
  barplot(x,col=cols)
}, finally = {
  dev.off()
})
on.exit(unlink(file))
value <- external_img(src = file, width = 5, height = 5)
body_add(doc, value)

print(doc, target = tempfile(fileext = ".docx"))
Robert
  • 924
  • 1
  • 9
  • 20
1

The code is generating the following error

Error in barplot.default(x, col = cols) : 
  'height' must be a vector or a matrix 

The issue here is that function body_add has an argument x and you are defining an x before the call. Changing the name to something else solves the issue:

z <- 1:5
cols=2:6
anyplot <- plot_instr(code = {
  barplot(z, col = cols)
})

doc <- read_docx()
doc <- body_add(doc, anyplot, width = 5, height = 4)
print(doc, target = "temp.docx")
David Gohel
  • 9,180
  • 2
  • 16
  • 34