0

Two questions:

  1. How do I add a line to the top of a table that I've made using tableGrob?

Here is my code with my data:

library(gridExtra)
library(grid)
library(gtable)

find_cell <- function(table, row, col, name="core-bg"){
  l <- table$layout
  which(l$t==row & l$l==col & l$name==name)
}

tt3 <- ttheme_minimal(base_size = 8,
                      colhead = list(fg_params = list(fontface=c(1,3,3))))

lintable <- data.frame("Comparison" =   c("Early/Late", "Early/Tips",   "Late/Tips"),
                       "Z" =    c(-2.098,   -6.077, -3.57),
                       "p" =    c(0.036,    "< 0.001",  "< 0.001"))

lint <- tableGrob(lintable, rows = NULL, theme = tt3)

ind <- find_cell(lint, 2, 3, "core-bg")
ind1 <- find_cell(lint, 3, 3, "core-bg")
ind2 <- find_cell(lint, 4, 3, "core-bg")
lint$grobs[ind][[1]][["gp"]] <- gpar(fill="gray83", col = NA)
lint$grobs[ind1][[1]][["gp"]] <- gpar(fill="gray83", col = NA)
lint$grobs[ind2][[1]][["gp"]] <- gpar(fill="gray83", col = NA)
lint1 <- gtable_add_grob(lint,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(0,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(0,"npc"),
                           gp = gpar(lwd = 1)),
                         t = 1, l = 1, r = ncol(lint))
lint2 <- gtable_add_grob(lint1,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(0,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(0,"npc"),
                           gp = gpar(lwd = 1)),
                         t = 4, l = 1, r = ncol(lint1))
lint3 <- gtable_add_grob(lint2,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(0,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(0,"npc"),
                           gp = gpar(lwd = 1)),
                         t = 0, l = 1, r = ncol(lint2))

grid.draw(lint3)

But I get this error:

Error in grid.Call.graphics(C_setviewport, vp, TRUE) : invalid 'layout.pos.row'

I've checked and the code works fine for everything up to and including making lint2. The error is associated with lint3. I know it is because I've specified t = 0 but I don't know how else to specify the top border of the first row.

  1. How can I inset the above table into another plot made up of multiple other plots?

The code for the plot to inset the table into is below:

library(ggpubr)

a <- data.frame("group2" = letters[1:2],
                "Rate" = sample(0:100, 20, replace = TRUE))
ap <- ggplot(a, aes(x=group2, y=Rate))+ 
  geom_boxplot(show.legend = F, fill = "gray83", lwd=0.2, fatten = 1)+
  ylab("Rate")+
  theme_classic()+
  theme(axis.title.x=element_blank())+
  theme(text = element_text(size=12))+
  theme(axis.title=element_text(size=11))

b <- data.frame("group2" = letters[1:2],
                "Rate" = sample(0:100, 20, replace = TRUE))
bp <- ggplot(b, aes(x=group2, y=Rate))+ 
  geom_boxplot(show.legend = F, fill = "gray83", lwd=0.2, fatten = 1)+
  ylab("Rate")+
  theme_classic()+
  theme(axis.title.x=element_blank())+
  theme(text = element_text(size=12))+
  theme(axis.title=element_text(size=11))

c <- data.frame("group2" = letters[1:2],
                "Rate" = sample(0:100, 20, replace = TRUE))
cp <- ggplot(c, aes(x=group2, y=Rate))+ 
  geom_boxplot(show.legend = F, fill = "gray83", lwd=0.2, fatten = 1)+
  ylab("Rate")+
  theme_classic()+
  theme(axis.title.x=element_blank())+
  theme(text = element_text(size=12))+
  theme(axis.title=element_text(size=11))

gt <- arrangeGrob(ap,bp,cp,
                  layout_matrix = rbind(c(1),c(2),c(3)))
p <- as_ggplot(gt) +                      
  draw_plot_label(label = c("A", "B", "C"), size = 12,
                  x = c(0, 0, 0), y = c(1, 0.66, 0.33))
p

R doesn't seem to think that the table is a grob (but is.grob returns as TRUE), which seems to be causing issues. Unfortunately, I have no idea where to start with figuring this out...

Any help with either question would be appreciated!

Many thanks,

Carolina

Edit: I've figured out the second part using this code:

pushViewport(viewport(x=0.1, y=0.77, w=0.25, h=0.25, just=c("left", "bottom")))
grid.draw(lint2)
pushViewport(viewport(x=0.37, y=-0.97, w=0.25, h=0.25, just=c("left", "bottom")))
grid.draw(lint1)
pushViewport(viewport(x=0.37, y=-4.9, w=0.25, h=0.25, just=c("left", "bottom")))
grid.draw(lint)

The issue is that if I adjust the viewport in any way, the insets don't stay in the relative position that I placed them. Is there a way of permanently fixing the insets in place so that if I move the viewport, they stay in the same place relative to the rest of the plot?

1 Answers1

2

You can draw the lines on the table like this:

lint1 <- gtable_add_grob(lint,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(1,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(1,"npc"),
                           gp = gpar(lwd = 1)),
                         t = 1, l = 1, r = ncol(lint))
lint2 <- gtable_add_grob(lint1,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(1,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(1,"npc"),
                           gp = gpar(lwd = 1)),
                         t = 2, l = 1, r = ncol(lint1))
lint3 <- gtable_add_grob(lint2,
                         grobs = segmentsGrob(
                           x0 = unit(0,"npc"),
                           y0 = unit(0,"npc"),
                           x1 = unit(1,"npc"),
                           y1 = unit(0, "npc"),
                           gp = gpar(lwd = 1)),
                         t = 4, l = 1, r = ncol(lint2))

grid.newpage()
grid.draw(lint3)

enter image description here

It seems like you are making things harder for yourself by using grid directly rather than higher-level interfaces such as geom_table from ggpmisc and plot arrangements using patchwork

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Great thank you! I tried to use what you suggested but couldn't get those to work either... At least now I have working code that's done the job! :) – Carolina Karoullas Nov 18 '20 at 14:27