I have to produce data listings with quite long tables that have to be displayed on several pages and I want to collapse some rows (ex: ID).
I'm using the package kable
to produce the tables and the collapse_row
function to collapse my ID rows.
When I knit to pdf, the alignment in the column with the collapsed rows is totally messed up and I even got ID appearing out of the table or incrusted in the repeated header...
Here is my code :
kable(data, "latex", booktabs = T,longtable = T, linesep = "", row.names = FALSE) %>%
kable_styling(full_width = T,
position = "center",
latex_options = c("striped", "repeat_header","hold_position"),
font_size = 6,5)%>%
column_spec(c(1), color = "black", width = "5em")%>%
column_spec(c(2), color = "black", width = "30em")%>%
collapse_rows(1, latex_hline = "custom",valign = "top")%>%
row_spec(0, bold = T, color = "black")
and this is a crop of what my pdf output looks like :
The lines are well placed but the ID shifted to the top.
How can I fix this ? Thanks.
Looks like a LaTeX issue with vertical alignment in tables.
A quote from the issue on github:
[...]it seems like booktabs' cmidrule messed up the multirow's calculation..
[...] I don't know if I can find a good solution for this. I can certainly remove those midlines. I don't like them either but they are important for tables with multiple header columns. If we keep those midlines, TeX people say you can manually add adjustments to multirow. I can certainly simulate it via code but it seems like it will bring me more issues in the future.
Source: https://github.com/haozhu233/kableExtra/issues/56
Additional references:
This solution worked well in my case when I had the same problem. The solution is based on manipulating the data.frame before outputting to kable rather than changing the kable output with collapse_rows. The original contributor (Michael Harper) developed it for use with the formattable package, but it can be easily adjusted for the kable package.
You need to declare this function:
collapse_rows_df <- function(df, variable){
group_var <- enquo(variable)
df %>%
group_by(!! group_var) %>%
mutate(groupRow = 1:n()) %>%
ungroup() %>%
mutate(!!quo_name(group_var) := ifelse(groupRow == 1, as.character(!! group_var), "")) %>%
select(-c(groupRow))
}
The function strips all but first encounters of data in the specified column, leaving blank spaces instead.
You need to call the function before sending the data to kable. See the example below:
library(knitr) # required for kable()
# dfToKable - your data.frame you need to kable
# columnToCollapseRows - the name of the column, in which you want to collapse the rows;
# it should be a valid variable within the data.frame set and be passed without quotes
kable( collapse_rows_df( dfToKable, columnToCollapseRows ),
row.names = F, escape = F, longtable = TRUE) %>%
kable_styling(full_width = T, latex_options = c("repeat_header"))
Based on the code and screenshot you provided, this should work for you:
kable( collapse_rows_df( data, SubID) "latex", booktabs = T,longtable = T, linesep = "", row.names = FALSE) %>%
kable_styling(full_width = T,
position = "center",
latex_options = c("striped", "repeat_header","hold_position"),
font_size = 6,5)%>%
column_spec(c(1), color = "black", width = "5em")%>%
column_spec(c(2), color = "black", width = "30em")%>%
row_spec(0, bold = T, color = "black")