You can use nested arrangeGrob
calls like this example:
library(ggplot2)
library(gridExtra)
p <- ggplot(data.frame(x=1, y=1), aes(x,y)) + geom_point()
grid.arrange(
arrangeGrob(
p,
arrangeGrob(p, p, nrow=2),
ncol=2 ,widths=c(2,1)),
arrangeGrob(p, p ,p ,ncol=3, widths=rep(1,3)),
nrow=2)
Edit:
gl <- lapply(1:9, function(ii) grobTree(rectGrob(),textGrob(ii)))
grid.arrange(
arrangeGrob(gl[[1]],
do.call(arrangeGrob, c(gl[2:5], ncol=2)),
nrow=1,
widths=3:2),
do.call(arrangeGrob, c(gl[6:9], nrow=1, list(widths=c(1,1,1,2)))),
nrow=2, heights=c(2,1))