Grouping Rows in an R Markdown Table - r

I'm new to R Markdown and I'm trying to make a table which looks like this:
The format of output file has to be PDF.
The goal is that I select a row from the big data frame and then put different variables of this row to table with the desired look. The most difficult in that table for me is to create a row with text which spans over all columns. How can I do this?
I can imagine how to do this with HTML tags (with colspan attribute) but I guess that it will not work with PDF...

Check out Hao Zhu's package kableExtra, which extends the functionality of the popular knitr package (referenced in the comment from #dshkol above) and allows for really easy grouping and labeling of rows.
The GitHub repository has a lot of great demos on how to group and subset tables in both HTML and LaTeX (which can then be output to PDF). For what you're trying to do, I would check out the LaTeX tutorial, under the section "Grouped Columns / Rows".
Example (borrowed from the tutorial):
library(knitr) # loads the kable package required for kableExtra
library(kableExtra)
dt <- mtcars[1:10, 1:6]
kable(dt, format = "latex", caption = "Group Rows", booktabs = T) %>%
kable_styling() %>%
group_rows("Group 1", 4, 7) %>%
group_rows("Group 2", 8, 10)

Related

using subscripts in gtsummary in R

Context
I am making a table and saving it into Microsoft Word with .docx file.
the table has a variable named PM2.5. I want to subscript 2.5 like PM2.5.
In this answear, I can use the grammar 'PM~2.5~' with as_kable() to use subscrpit in PM2.5.
But when I save the result (tab), it is a blank .docx file.
Question
How can I use subscripts in gtsummary and save it into .docx file?
Reproducible code
library(dplyr)
library(gtsummary)
df = data.frame(PM2.5 = 1)
tab = # make a table using gtsummary
df %>%
tbl_summary(label = PM2.5 ~ 'PM~2.5~') %>% # subscript in main table
modify_table_styling(columns = label,
rows = label == 'PM~2.5~',
footnote = 'PM~2.5~ in footnote') %>% # subscript in footnote
as_kable()
tab %>% flextable::save_as_docx(path = 'test.docx') # a blank .docx file
The reason it is blank is because you're using flextable::save_as_docx() to save the table. That function will only work with flextables...not knitr::kable() tables.
You can put this table in an R markdown or Quarto document with output type Word, and the table will appear.

Convert a "table1"-table to pdf-friendly format

I have a table with descriptive statistics I generated using the table1 package (I used it since it can produce descriptive statistics for both categorical and continuous variables). The issue I'm having is that table1 only produce tables in HTML-format. I'd like to transform my table1-table to a kable-table (or equivalent) so I knit my markdown to a pdf-file.
I tried the following code
library(table1)
library(kable)
tb <- table1(reformulate(colnames(df)), data=df, output = "latex")
kable(tb, caption = "Descriptive statistics")
But this produces an empty table looking like this:
Does anyone know how to solve this?

How to set automatic output format of all my tables in Rmarkdown?

I am writing an Rmarkdown document with plenty of tables, and I want them in a decent format, e.g. kable. however I don't want to format them one by one. Is there any easy way to knit the document such that the output format of every table would be kable style?
For example, I have created the following data frame in dplyr
data2 %>%
group_by(uf) %>%
summarise(n = n(), ) %>% arrange(desc(n))
And I just want that query to have a kable style automatically, avoiding giving a name to the query and avoiding the kable function over that name. Why do I want it like this? Because of my document has hundreds of these dplyr queries and I need a faster way to knit the document.
Thanks!
Just write a function to do what you want. For example,
mykable <- function(x) kable(x, digits = 2, format.args = list(big.mark = ","))
then use
mykable(df)
to format df using those options.
I found the answer by using the printr package.

How to split kable over multiple columns?

I am trying to produce a "longitudinal" layout for long tables in RMarkdown with kable. For example, I would like a table to be split over two columns, like in the example below:
dd <- data.frame(state=state.abb, freq=1:50)
kable(list(state=dd[1:25,], state=dd[26:50,]))
However, this hack produces an output that looks a way worse than the normal kable output (for example the header is not in bold). Is there a "proper" way to do this using kable?
kable is a great tool, but has limits. For the type of table you're describing I would use one of two different tools depending on output wanted.
Hmisc::latex for .Rnw -> .tex -> .pdf
htmlTable::htmlTable for .Rmd -> .md -> .html
Here is an example of the latter:
dd <- data.frame(state=state.name, freq=1:50)
dd2 <- cbind(dd[1:25, ], dd[26:50, ])
library(htmlTable)
htmlTable(dd2,
cgroup = c("Set 1:25", "Set 26:50"),
n.cgroup = c(2, 2),
rnames = FALSE)
You can still use Kable with a slight modification to your code.
dd <- data.frame(state=state.abb, freq=1:50)
knitr::kable(
list(dd[1:25,], dd[26:50,]),
caption = 'Two tables placed side by side.',
booktabs = TRUE
)
This code is a modification of this. You can also find more information about tables on that page

Combine tables in R Markdown

I am trying to combine two tables in R Markdown into a single table, one below the other & retaining the header. The figure below shows the desired output. After putting my markdown code I will show the actual output. I realize that the way I have structured the pander statements will not allow me to get the output I want but searching SO I was unsuccessful in finding the right way to do so.
I can do some post processing in Word to get the output exactly as I want but I am trying to avoid that overhead.
The testdat.RData file is here: https://drive.google.com/file/d/0B0hTmthiX5dpWDd5UTdlbWhocVE/view?usp=sharing
The R Markdown RMD file is here: https://drive.google.com/file/d/0B0hTmthiX5dpSEFIcGRNQ1MzM1E/view?usp=sharing
Desired Output
```{r,echo=FALSE,message = FALSE, tidy=TRUE}
library(pander)
load("testdat.RData")
pander::pander(t1,big.mark=',', justify=c('left','right','right','right'))
pander::pander(t2,big.mark=',', justify=c('left','right','right','right'))
```
Actual Output
Thanks,
Krishnan
Here's my attempt using the xtable package:
```{r,echo=FALSE, message = FALSE, results="asis"}
library(xtable)
# Add thousands separator
t1[-1] = sapply(t1[-1], formatC, big.mark=",")
t2[-1] = sapply(t2[-1], formatC, big.mark=",")
t1$Mode = as.character(t1$Mode)
# Bind together t1, extra row of column names, and t2
t1t2 = rbind(t1, names(t1), t2)
# Render the table using xtable
print(xtable(t1t2, align="rrrrr"), # Right-align all columns (includes extra value for row names)
include.rownames=FALSE, # Don't print rownames
hline.after=NULL,
# Add midrules before/after each set column names
add.to.row = list(pos = list(-1,0,4,5),
command = rep("\\midrule \n",4)))
```
And here's the output:
Allow me to make a formal answer since my comment seemed to work for you.
pander(rbind(t1,names(t2),t2))

Resources