rkablekableextra

kableExtra html table: pack_rows() ignores  


I am rendering an html document in Quarto (engine: knitr). I have added some trailing whitespaces in a kableExtra table using " ". However, as soon as I add pack_rows() to the mix, " " is rendered as text in the table. Any idea why this is happening and how I can fix it? Using escape = FALSE within kable() does not help.

This works as intended:

library(tidyverse)
library(kableExtra)

set.seed(404)

mtcars_tbl <- 
  mtcars %>% 
  mutate(
    p = round(runif(nrow(.), 0, .1), 2),
    p = case_when(
      p < .05 ~ paste0(p, "*"),
      TRUE ~ paste0(p, "&nbsp;&nbsp;")
    )
  ) %>%
  select(mpg, hp, p)

mtcars_tbl %>% 
  head() %>% 
  kable(align = "lrrr")

kableExtra table with trailing whitespaces correctly rendered in the last column.

This does not:

mtcars_tbl %>% 
  head() %>% 
  kable(align = "lrrr") %>% 
  pack_rows(index = c("group 1" = 3, "group 2" = 3))

kableExtra table where pack_rows() prevents trailing whitespace from being rendered in the last column.

Thanks in advance for any tips!


Solution

  • When you add pack_rows(), HTML entities like &nbsp; are being treated as literal text rather than being interpreted as HTML. But, you can use unicode spaces instead `"\u00A0\u00A0":

    out

    Code

    ```{r}
    #| echo: false
    
    library(tidyverse)
    library(kableExtra)
    
    set.seed(404)
    mtcars_tbl <- 
      mtcars %>% 
      mutate(
        p = round(runif(nrow(.), 0, .1), 2),
        p = case_when(
          p < .05 ~ paste0(p, "*"),
          TRUE ~ paste0(p, "\u00A0\u00A0")
        )
      ) %>%
      select(mpg, hp, p)
    
    mtcars_tbl %>% 
      head() %>% 
      kable(align = "lrrr", escape = FALSE) %>% 
      pack_rows(index = c("group 1" = 3, "group 2" = 3))
    
    ```
    

    If you want to do something similar for more significance values (**, ***) you can pad whitespaces based on the most significant p-value:

    out2

    Code - conditional padding

    ---
    title: "add spaces"
    format: html
    editor: visual
    ---
    
    ## Quarto
    
    ```{r}
    #| echo: false
    
    library(tidyverse)
    library(kableExtra)
    
    set.seed(404)
    mtcars_tbl <- 
      mtcars %>% 
      mutate(
        p = round(runif(nrow(.), 0.003, .012), 3),
        p = case_when(
          p < .05 & p >= 0.01  ~ paste0(p, "*"),
          p < .01 ~ paste0(p, "**"),
          TRUE ~ as.character(p)  # Convert to character before processing
        )
      ) %>%
      mutate(
        max_length = max(nchar(p)),  # Get max string length
        p = str_pad(p, width = max_length, side = "right", pad = "\u00A0")  # Pad with non-breaking spaces
      ) %>%
      select(mpg, hp, p)
    
    mtcars_tbl %>% 
      head() %>% 
      kable(align = "lrrr", escape = FALSE) %>% 
      pack_rows(index = c("group 1" = 3, "group 2" = 3))
    
    ```