4

I'm trying to export a ggsurvplot-object to powerpoint with officer-package with no success. I was able to find a lot of instructions on how to use now obsolute ReporterS-package for this and a few mentions that officer should work as well. There seems to be nothing in the documentation mentioning this. So should this work at all? Is it possible to get a vectorized survival plot to a pptx-slide with these tools?

totsur <- ggsurvplot(yhd1,
           data = sappivertailu,
           combine=TRUE,
           xlab = "Time, months", 
           ylab="Survival", 
           title="Overall survival",
           lwd=2,
           palette="jco",
           xscale = "d_m",
           xlim = c(0,730.5),
           break.x.by = 91.3,
           risk.table = TRUE,
           pval = TRUE,
           fontsize = 3)
totsur
my_vec_graph <- dml(code = totsur)

doc <- read_pptx()
doc <- add_slide(doc, layout = "Overall survival", master = "Office Theme")
doc <- ph_with(doc, my_vec_graph, location = ph_location_fullsize() )
print(doc, target = "Sappitutkimus/Charts/survi1.pptx")

Changing the dml(ggobj = totsur) neither works. What am I doing wrong?

Edit: Thanks for all the comments below! And another update. There was nothing wrong with the data. After a little debugging, my original data produces the intended result.

One problem remains. Package does not seem to able to add risk table and survival curve in the same slide. Yes, you can pass this by making two separate plots on separate slides but I don't think that's good practice.

If I'm not totally mistaken, officer and ReporteRs have some code in common and this issue was present there as well. https://github.com/kassambara/survminer/issues/314

Does anyone know a way around this? Here's a bit more compact chunk I'm currently using. This works fine otherwise.

yhd1 <- survfit(Surv(sappivertailu$Survi, sappivertailu$Kuolema) ~ Arm, data=koe)

totsur <- 
  ggsurvplot(yhd1,
           combine = TRUE,
           data = sappivertailu,
      #     risk.table = TRUE,
           pval = TRUE,
           fontsize = 3
           )
totsur
my_vec_graph <- rvg::dml(ggobj = last_plot())

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, my_vec_graph, location = ph_location_fullsize() )
print(doc, target = "Sappitutkimus/Charts/survi1.pptx")

Edit n:o 2: And a tip about the desired result. Number at risk table included

  • Can't you export as pdf and import into pptx as a vector? – jared_mamrot Jan 24 '21 at 10:10
  • Yep. I can do that in steps and it works fine. Also saving to .eps works as well. However for the sake of workflow, I would greatly appreciate the possibility to make R do the job and create a ready made pptx with all the necessary information. – Lauri Pautola Jan 24 '21 at 11:11

2 Answers2

3

Sure could you export ggsurvplots. to pptx via officer. There are two issues with your code. First you have to make use of rvg::dml(ggobj = ...) . Second you set layout = "Overall survival". But there is no layout with this name in the default pptx shipped with officer, i.e. you could only use layouts which are present in the pptx template. Fixing both issues and making use of the basic example from the docs of ggsurvplot:

require("survival")
#> Loading required package: survival
library(survminer)
#> Loading required package: ggplot2
#> Loading required package: ggpubr
library(officer)

fit<- survfit(Surv(time, status) ~ sex, data = lung)

# Basic survival curves
ggsurvplot(fit, data = lung)


my_vec_graph <- rvg::dml(ggobj = last_plot())

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, my_vec_graph, location = ph_location_fullsize() )
print(doc, target = "survi2.pptx")

enter image description here

EDIT If you want to have multiple contents on the same slide you could change the layout to Two Content and make use of ph_location_left/right:

doc <- read_pptx()
doc <- add_slide(doc, layout = "Two Content", master = "Office Theme")
doc <- ph_with(doc, my_vec_graph, location = ph_location_left() )
doc <- ph_with(doc, my_vec_graph, location = ph_location_right() )
print(doc, target = "survi2.pptx")
stefan
  • 90,330
  • 6
  • 25
  • 51
  • Great, thanks! So it works and that's easily reproducible. I did both modifications. However my original chart still doesn't print. It gives this warning:"Error in read_xml.raw(charToRaw(enc2utf8(x)), "UTF-8", ..., as_html = as_html, : StartTag: invalid element name [68]" It is not related to any of arguments in ggsurvplot. Neither does removing labels from vectors used work. Any ideas? – Lauri Pautola Jan 24 '21 at 15:14
  • Hi Lauri. Have you made the change to `rvg::dml(ggobj = ...`?? I'm asking because when I use `rvg::dml(code = ...` I get exactly the same error message as you do. – stefan Jan 24 '21 at 17:10
  • Thanks again, a silly mistake! Now I'm able to get a plot out with the same exact code you just gave. Still I have a problem though. Now when I use the argument "last_plot()", it only produces risk table. If I try to get around this by putting ggsurvplot to an object and put that instead of "last_plot()", the R session completely crashes without a traceback. Same happens if I print the plot first and then use last_plot(). Since the data is originally imported from SPSS-file and manipulated in R, there might be some issue with data type I guess? – Lauri Pautola Jan 24 '21 at 20:53
  • Ok, a short update. The reason was crashing was again silly. I had Powerpoint and the file to be written open. So there's a bug in officer, but it is easy to get pass by. Now I'm able to get the risktable to pptx but not the survival curves. I'll play around with this a little and see if it is indeed the data type in original dataset that causes the trouble. – Lauri Pautola Jan 25 '21 at 06:20
  • Just a quick remark. I edited the original post and put the hopefully final issue in there. Code works out fine now and data was not the issue, but getting risk table and survival curve on the same slide seems to be. Hope you, or someone else knows a way around this. – Lauri Pautola Jan 25 '21 at 07:34
  • Not sure about your desired final result. But if you want two contents on one slide you could switch the layout. See my edit. – stefan Jan 25 '21 at 12:41
  • Ah, yeah. See my new edit. I got the same exact idea but then abandoned it for a few reasons. First, you have to make two similar ggsurvplot-objects. Another without risk table and another with. Since I was able to get last_plot()-method work, it would have to be in between two chunks. Second reason is, it is quite difficult to create a readable risk table and a method this complicated would make it a fuss. Then last reason was that I was unable to find ph_location_template or other argument that would be controllable in a desired way. Have to find someting else. – Lauri Pautola Jan 25 '21 at 21:19
  • Ok, some more research and I found this. https://github.com/davidgohel/officer/issues/244 So in case I add a risk table, ggsurvplot creates two graphics another one of which is empty, and it messes up with officer. So this might be a bug in survminer after all. – Lauri Pautola Jan 25 '21 at 21:35
1

Somewhat to my amazement, you can use the code = argument within dml() if you embed your suvival plot in a print() statement. Be sure to include newpage = FALSE:

require("survival")
# Loading required package: survival
library(survminer)
#> Loading required package: ggplot2
#> Loading required package: ggpubr
library(officer)

fit<- survfit(Surv(time, status) ~ sex, data = lung)

# Basic survival curves
p = ggsurvplot(fit, data = lung, risk.table = TRUE)
    
my_vec_graph <- rvg::dml(code = print(p, newpage = FALSE))

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, my_vec_graph, location = ph_location_fullsize() )
print(doc, target = "survi2.pptx")