9

I'm new to knitr (and also quite new to R), so this might be a dumb question...

I have two data.frames, which both have two columns, but different numbers of rows. I want to show them in my knitr report, but having one narrow table below another narrow table when they could so easily sit next to each other doesn't look good. Is there any way they could be displayed next to each other?

Update

Ok, based on the suggestion below, here's what I did (I'm putting three tables together now):

```{r fig.height=13.5, fig.width=10, echo=FALSE, comment=""}
grid.arrange(textGrob("Visual Clusters", gp=gpar(fontsize=14, fontface="bold")),
             textGrob("We have biofilm data for...", gp=gpar(fontsize=14, fontface="bold")),
             textGrob("Left Over Isolates", gp=gpar(fontsize=14, fontface="bold")),
             tableGrob(clusters, show.rownames=FALSE, gp=gpar(fontsize=10)),
             tableGrob(clust_ab, show.rownames=FALSE, gp=gpar(fontsize=10)),
             tableGrob(n_clust, show.rownames=FALSE, gp=gpar(fontsize=10)),
             ncol=3, nrow=2, heights=c(1,30))
```

This looks already really good, with titles for the three tables and without the numbered rows.
The only issue I couldn't resolve so far is that the tables are all centred horizontally, so the shorter ones start below the longest one, if you know what I mean.

Lilith-Elina
  • 1,613
  • 4
  • 20
  • 31

2 Answers2

14

The development version of knitr (on Github; follow installation instructions there) has a kable() function, which can return the tables as character vectors. You can collect two tables and arrange them in the two cells of a parent table. Here is a simple example:

```{r two-tables, results='asis'}
library(knitr)
t1 = kable(mtcars, format='html', output = FALSE)
t2 = kable(iris, format='html', output = FALSE)
cat(c('<table><tr valign="top"><td>', t1, '</td><td>', t2, '</td><tr></table>'),
    sep = '')
```

You can also use CSS tricks like style="float: [left|right]" to float the tables to the left/right.

If you want to set cell padding and spacing, you can use the table attributes cellpadding / cellspacing as usual, e.g.

```{r two-tables, results='asis'}
library(knitr)
t1 = kable(mtcars, format='html', table.attr='cellpadding="3"', output = FALSE)
t2 = kable(iris, format='html', table.attr='cellpadding="3"', output = FALSE)
cat(c('<table><tr valign="top"><td>', t1, '</td>', '<td>', t2, '</td></tr></table>'),
    sep = '')
```

See the RPubs post for the above code in action.

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
  • Thanks! With this I can do exactly what I want and don't have to fight to get the tables placed right. – Lilith-Elina Jul 19 '13 at 08:25
  • Is there any way to influence cell padding and spacing in kable? My data frames have names in one column and single-digit numbers in the other and they are too close together to be comfortable to read. – Lilith-Elina Jul 19 '13 at 12:47
  • How do we add `style="float: [left|right]"` into the code? Thanks. – Paulo S. Abreu Sep 18 '18 at 20:30
5

Would you settle for "an image" of data.frames? Clearly my solution is crude, feel free to fiddle with the details (spacing between data.frames, for example).

Two data.frames, side by side
========================================================

```{r}
library(gridExtra)
x <- data.frame(a = runif(5), b = runif(5))
y <- data.frame(a = runif(7), b = runif(7))

grid.arrange(tableGrob(x), tableGrob(y), ncol = 2)
```

enter image description here

Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
  • Awesome, thanks! I have to fiddle with that to get the longer df (48 rows) in complete next to the shorter (only 7 rows), but it looks very promising. :-) – Lilith-Elina Jul 18 '13 at 09:05
  • this is great! do you know how i can get the 2 table to start at the same point? – eliavs Jul 10 '16 at 15:19