Search code examples
rdataframepdfplotlandscape

Saving dataframe to pdf adjust width


I found that grid.table could be used to plot a dataframe to a pdf file, as described here. I want to save a dataframe to a landscape A4 format, however it seems to not scale the data such that is nicely fits within the borders of the pdf.

Code

library(gridExtra)

set.seed(1)
strings <- c('Wow this is nice', 'I need some coffee', 'Insert something here', 'No ideas left')
table <- as.data.frame(matrix(ncol = 9, nrow = 30, data = sample(strings,30, replace = TRUE)))
pdf("test.pdf", paper = 'a4r')
grid.table(table)
dev.off()

Output
Not the whole table is shown in the pdf: enter image description here

Question
How can I make sure that the dataframe is scaled to fit within the landscape A4? I don't explicitly need gridExtra or the default pdf save, I can use any other package if these are easier to fix this.


EDIT

I came across this other question, appareantly one can figure out the required height and width of the tableGrob

tg = gridExtra::tableGrob(table)
h = grid::convertHeight(sum(tg$heights), "mm", TRUE)
w = grid::convertWidth(sum(tg$widths), "mm", TRUE)
ggplot2::ggsave("test.pdf", tg, width=w, height=h, units = 'mm')

Here h = 172.2 and w = 444.3 which exceed the size of a standard A4, namely 210 x 279. So I know this causes the problem however still can't figure out to scale down the table to fit it on an A4.


Solution

  • I figured out I could add the scale parameter to ggsave. I wrote a simple function to get the optimal scale:

    optimal.scale <- function(w,h, wanted.w, wanted.h) max(c(w/wanted.w, h/wanted.h))

    I added 0.1 to the scale to add a margin to the plot such that the text is not directly on the edge of the paper. Then I passed the resulting scale to ggsave

      tg = gridExtra::tableGrob(table
      h = grid::convertHeight(sum(tg$heights), "mm", TRUE)
      w = grid::convertWidth(sum(tg$widths), "mm", TRUE)
      scale = optimal.scale(w,h, 279, 210) + 0.1 #A4 = 279 x 210 in landscape 
      ggplot2::ggsave("test.pdf", tg, width = 279, height = 210, units = 'mm' , scale = scale)
    

    Now my table fits on the A4:

    enter image description here