Search code examples
rlatexconditional-formattingkable

Bold cells in kable (format = latex) based on rowwise largest value by group of variables


Working Example

set.seed(1234)
df <- data.frame(  x1 = rnorm(3), x2 = rnorm(3), z1 =rnorm(3), z2=rnorm(3))

which produces

 x1       x2       z1       z2
-------  -------  -------  -------
 -1.207   -2.346   -0.575   -0.890
  0.277    0.429   -0.547   -0.477
  1.084    0.506   -0.564   -0.998

I can then export to latex using

kable(df,format = "latex", digits = 3)

But I would like to have in bold the cells that are the largest across rows (x1 vs x2, and z1 vs z2). So in this example, x1=-1.207 and z1=-0.575 would be in bold in the first row, x2=0.429 and z2=-0.477 would be in bold in the second row, etc.

So that the final output should be

\begin{tabular}{r|r|r|r}
\hline
x1 & x2 & z1 & z2\\
\hline
\textbf{-1.207} & -2.346 & \textbf{-0.575} & -0.890\\
\hline
0.277 & \textbf{0.429} & -0.547 & \textbf{-0.477}\\
\hline
\textbf{1.084} & 0.506 & \textbf{-0.564} & -0.998\\
\hline
\end{tabular}

Any help would be great!


Solution

  • Using cell conditional formatting from kableExtra coupled with tidyverse packages this is one attempt, although I'd be the first to admit it seems alot of work.

    I'm sure there is a better way.

    ```{r results='asis'}
    
    library(dplyr)
    library(tidyr)
    library(tibble)
    library(stringr)
    library(kableExtra)
    
    set.seed(1234)
    
    df <-
      data.frame( x1 = rnorm(3), x2 = rnorm(3), z1 = rnorm(3), z2 = rnorm(3)) %>%
      rowid_to_column() %>%
      pivot_longer(-rowid)%>%
      mutate(group = str_sub(name, 1, 1),
      id = str_sub(name, -1, -1)) %>%
      group_by(group, rowid) %>%
      mutate(value = round(value, 3),
      value = ifelse(value == max(value), cell_spec(sprintf("%.3f", value), "latex", bold = TRUE),
                     sprintf("%.3f", value))) %>%
      ungroup() %>%
      select(-c(group, id)) %>%
      pivot_wider() %>% 
      select(-rowid)
    
    
    kbl(df,
        booktabs = TRUE,
        escape = FALSE,
        align = "r")
    ```
    

    enter image description here