1

I have a markdown document using a bit of LaTeX to produce a .pdf with the following chunk:

grid.arrange(
  grobs = list(
    gtable_combine(
      gtable_add_grob(
        tableGrob(mtcars[1:3, 1:2], rows = NULL),
        grobs = segmentsGrob(y1 = unit(0, "npc"),
        gp = gpar(fill = NA, lwd = 2)),
        t = 1,
        l = 1,
        r = ncol(mtcars[1:3, 1:2])
        ),
      gtable_add_grob(
        tableGrob(mtcars[1:3, 1:2], rows = NULL),
        grobs = segmentsGrob(y1 = unit(0, "npc"),
        gp = gpar(fill = NA, lwd = 2)),
        t = 1,
        l = 1,
        r = ncol(mtcars[1:3, 1:2])
        ),
        along = 2), 
    gtable_add_grob(
      tableGrob(mtcars[1:8, 1:2], rows = NULL),
      grobs = segmentsGrob(y1 = unit(0, "npc"),
                           gp = gpar(fill = NA, lwd = 2)),
      t = 1,
      l = 1,
      r = ncol(mtcars[1:8, 1:2])
      )
    ),
  ncol = 2
  )

The output is centre aligned, and I would like it aligned at the top. My sticking point is that the left hand side is two combined tables already, and I seem to be unable to nest the output of that function into another cal to gtable_combine(). I also haven't had any luck using the layout_matrix= argument in gridExtra, as this adds a huge amount of space between the left two tables.

How can I have the left two tables very close (adjoined is fine), and also have the top of the top-most left table and the top of the right table horizontally aligned?

DaveRGP
  • 1,430
  • 15
  • 34

2 Answers2

0

try

library(gridExtra)

t1 <- tableGrob(mtcars[1:3,], rows = NULL)
t2 <- tableGrob(mtcars[1:8,], rows = NULL)

grid.draw(gtable_combine(t1, t2))

enter image description here

  • 1
    Can you add a short description of what exactly the OP should do with this code or where to put it? – Bonifacio2 Jan 24 '18 at 12:14
  • Thanks for the suggestion, but a key part of my requirements is to have 3 tables, not two, which you have here, arranged so that the two shorter tables are close to each other with the bottom of one being adjacent to the top of the other, then that *combination* of short tables is top aligned and positioned to the right of the longer table. – DaveRGP Jan 29 '18 at 14:27
0

I've located an answer from this prior SO post. It appears to me that the padding of the output of the two shorter tables gtable_combine(...) differs from the output of the longer table as the top padding is by default a function of the length of the table, and here the two tables, even when combined, will differ in length. The function @baptiste outlines in his answer solves this problem by fixing that padding value. Implementing it in my use case looks like this:

justify <- function(x, hjust="center", vjust="top", draw=FALSE){
  w <- sum(x$widths)
  h <- sum(x$heights)
  xj <- switch(
    hjust,
    center = 0.5,
    left = 0.5 * w,
    right = unit(1, "npc") - 0.5 * w
    )
  yj <- switch(
    vjust,
    center = 0.5,
    bottom = 0.5 * h,
    top = unit(1, "npc") - 0.5 * h
    )
  x$vp <- viewport(x=xj, y=yj)
  if(draw) grid.draw(x)
  return(x)
}

grid.arrange(
  justify(
    gtable_combine(
      gtable_add_grob(
        tableGrob(mtcars[1:3, 1:2], rows = NULL),
        grobs = segmentsGrob(y1 = unit(0, "npc"),
                             gp = gpar(fill = NA, lwd = 2)),
        t = 1,
        l = 1,
        r = ncol(mtcars[1:3, 1:2])
        ),
      gtable_add_grob(
      tableGrob(mtcars[1:3, 1:2], rows = NULL),
      grobs = segmentsGrob(y1 = unit(0, "npc"),
                           gp = gpar(fill = NA, lwd = 2)),
      t = 1,
      l = 1,
      r = ncol(mtcars[1:3, 1:2])
      ),
      along = 2
      )
    ), 
  justify(
    gtable_add_grob(
      tableGrob(mtcars[1:8, 1:2], rows = NULL),
      grobs = segmentsGrob(y1 = unit(0, "npc"),
                           gp = gpar(fill = NA, lwd = 2)),
      t = 1,
      l = 1,
      r = ncol(mtcars[1:3, 1:2])
      )
    ),
  ncol = 2
  )
DaveRGP
  • 1,430
  • 15
  • 34