2

I am trying to automate a series of analyses which are intended to save a number of plots for later inspection. One of the plots will be accompanied by a table of values. I'd like to have them in the same pdf so that the users don't have to jump between files.

I have checked numerous questions on SO regarding outputting data frames to pdf, here are a couple of reasons why existing answers aren't satisfactory in my case:

  • Not familiar with knitr/Sweave
  • Batch generation of figures mean that I cannot do it manually via RStudio Viewer
  • grid.table based solutions do not generate the entire table.

Which brings me to my problems, say I have a table 48 x 5 in proportions. If I try to plot it out with grid.table(geno) it results in a cropped table showing some 20-30 rows in the middle. If I go with grid.table(geno, gp = gpar(fontsize=8)) to decrease the fontsize I get the following error message.

Error in gtable_table(d, name = "core", fg_fun = theme$core$fg_fun, bg_fun = theme$core$bg_fun,  : 
  unused argument (gp = list(fontsize = 8)

)

Essentially I would like to be able to use it in this way:

library(grid)
library(gridExtra)
pdf(file="gtype.pdf", title = "Genotype data")
plotGenotype(geno, text_size = 10)    # outputs a custom plot
grid.newpage()
grid.table(geno)         # grid.table(geno, gp = gpar(fontsize=8))
dev.off()

The problem here is that I either get a cropped table or nothing at all, on the second page. I noticed that many people add height=11, width=8.5 to the pdf() call. I am not sure if/why that would make a difference but setting paper="a4" or height/width according to A4 does not make any difference in my case.

Q1: Is it not possible to get grid.table to resize based on content and not paper?

Q2: Is there some other way to get a data frame printed to a pdf without having to go through LaTeX based solutions?

(I am currently running R 3.3.1 and gridExtra 2.2.1)

posdef
  • 6,498
  • 11
  • 46
  • 94
  • have you checked [this FAQ](https://github.com/baptiste/gridextra/wiki#problems-with-gridtable)? – baptiste Aug 03 '16 at 08:59
  • @baptiste thanks for the link. I have seen the examples/documentation but must have missed the FAQ somehow. I have ask though, where in [this example](http://stackoverflow.com/a/31620903/328725) does the fontsize gets adjusted? – posdef Aug 03 '16 at 09:12
  • 1
    font size is set in the theme, that's 7pts in `ttheme_default(7)` – baptiste Aug 03 '16 at 09:22
  • @baptiste thanks :) – posdef Aug 03 '16 at 09:25
  • for what it's worth, i'd strongly suggest moving toward a LaTeX solution/workflow; grid.table is intrinsically a very limited approach, and should typically be used for very basic (and small) tables. – baptiste Aug 03 '16 at 09:44

1 Answers1

2

Q1: Is it not possible to get grid.table to resize based on content and not paper?

It is possible, but generally not desirable. A table is meant to be read, and if text and spacings were determined by the page rather than the content, it would often yield unreadable results. Thus the usual advice: manually tweak the font size and padding, or split the table.

It is by no means a technical limitation: feel free to set the cell size to fit the page:

grid.newpage()
pushViewport(viewport(width=unit(0.8,"npc"), height=unit(0.8,"npc")))
g <- g2 <- tableGrob(iris[1:4, 1:3], cols = NULL, rows=NULL)
g2$heights <- unit(rep(1/nrow(g2), nrow(g2)), "npc")
grid.arrange(rectGrob(), rectGrob(), nrow=1, newpage = FALSE)
grid.arrange(g, g2, nrow=1, newpage = FALSE)

enter image description here

but with too much content for the page it's unclear what result is better

grid.newpage()
pushViewport(viewport(width=unit(0.8,"npc"), height=unit(0.8,"npc")))

g <- g2 <- tableGrob(iris[1:20, 1:3], cols = NULL, rows=NULL)
g3 <- tableGrob(iris[1:20, 1:3], cols = NULL, rows=NULL, theme=ttheme_default(base_size=7))
g2$heights <- g3$heights <- unit(rep(1/nrow(g2), nrow(g2)), "npc")
grid.arrange(rectGrob(), rectGrob(), rectGrob(), nrow=1, newpage = FALSE)
grid.arrange(g, g2, g3, nrow=1, newpage = FALSE)

enter image description here

If the page size can be changed, it is usually the best option. One can query the table size before drawing, convert it to inches, and pass it to the device.

g1 <- tableGrob(iris[1:4, 1:5])
g2 <- tableGrob(iris[1:20, 1:5])

maxheight <- convertHeight(sum(g2$heights), "in", TRUE)
pdf("fit.pdf", height=maxheight)
grid.draw(g1)
grid.newpage()
grid.draw(g2)
dev.off()

enter image description here

However, as far as I know all pages in a given pdf will have to have the same size (there might be ways around it, but tricky).

Community
  • 1
  • 1
baptiste
  • 75,767
  • 19
  • 198
  • 294
  • I see your point regarding the readability. Just for the record, I never suggested that the paper size should dictate the table sizing, on the contrary I fully agree that the content size should determine the size of table components. As I mentioned on the comment above, regarding the FAQ, I am not sure how the font-size is tweaked in the example you have given – posdef Aug 03 '16 at 09:18