Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wrapping wide table in rmarkdown

I have a really wide table (300+ columns) and would like to display it by wrapping the columns. In the example I will just use 100 columns.

What I have in mind is repetitively using kable to display the subset of the table:

library(kableExtra)
set.seed(1)
data = data.frame(matrix(rnorm(300, 10, 1), ncol = 100))

kable(data[, 1:5], 'latex', booktabs = T) 
kable(data[, 6:10], 'latex', booktabs = T) 
kable(data[, 11:15], 'latex', booktabs = T) 

But this is apparently tedious... I know there are scaling down options but since I have so many columns, it won't be possible.

Is there any parameter I can twist in kable to make it happen?


Updated: @jay.sf 's answer seems working well, but it didn't yield the same result here. Instead I got some plain code - could you please have a second look and let me know where can I improve? Thanks!

results

my sessionInfo() is: R version 3.5.1 (2018-07-02) with rmarkdown::pandoc_version() of 1.19.2.1.

like image 286
Rachel Zhang Avatar asked Mar 17 '19 14:03

Rachel Zhang


2 Answers

This question is actually trickier than I thought at first glance. I used some tidyverse functions, specifically dplyr::select to get columns and purrr::map to move along groups of column indices.

My thinking with this was to make a list of vectors of column indices to choose, such that the first list item is 1:20, the second is 21:40, and so on, in order to break the data into 20 tables of 5 columns each (the number you use can be a different factor of ncol(data)). I underestimated the work to do that, but got ideas from an old SO post to rep the numbers 1 to 20 along the number of columns, sort it, and use that as the grouping then to split the columns.

Then each of those vectors becomes the column indices in select. The resulting list of data frames each gets passed to knitr::kable and kableExtra::kable_styling. Leaving things off there would get map's default of printing names as well, which isn't ideal, so I added a call to purrr::walk to print them neatly.

Note also that making the kable'd tables this way meant putting results="asis" in the chunk options.

---
title: "knitr chunked"
output: pdf_document
---

```{r include=FALSE}
library(knitr)
library(kableExtra)
library(dplyr)
library(purrr)

set.seed(1)
data = data.frame(matrix(rnorm(300, 10, 1), ncol = 100))
```

```{r results='asis'}
split(1:ncol(data), sort(rep_len(1:20, ncol(data)))) %>%
  map(~select(data, .)) %>%
  map(kable, booktabs = T) %>%
  map(kable_styling) %>%
  walk(print)
```

Top of the PDF output:

pdf

like image 157
camille Avatar answered Nov 17 '22 17:11

camille


You could use a matrix containing your columns numbers and give it into a for loop with the cat function inside.

---
output: pdf_document
---

```{r, results="asis", echo=FALSE}
library(kableExtra)
set.seed(1)
dat <- data.frame(matrix(rnorm(300, 10, 1), ncol=100))

m <- matrix(1:ncol(dat), 5)

for (i in 1:ncol(m)) {
 cat(kable(dat[, m[, i]], 'latex', booktabs=TRUE), "\\newline")
}
```

Result

enter image description here

like image 2
jay.sf Avatar answered Nov 17 '22 19:11

jay.sf