rkablekableextra

How to fill entire cell of a table with cell_spec() in kabeleExtra?


Following on from this question posed a while ago, does anyone know how I can fill the entire background of a cell using the cell_spec() function in kableExtra?

I have some dummy data below, but I can only manage to colour the background of the text. I'd prefer the entire cell filled and I'm pretty set on using kableExtra to create my table within an R Markdown file. Does anyone know of a workaround for this? Thanks.

library(kableExtra)

name <- paste("Name", LETTERS)
val <- rnorm(26, 100, 50)
d <- data.frame(name, val)

d$val <- cell_spec(d$val, background = if_else(d$val > mean(d$val) + sd(d$val),
                                              "#DBEBF6",
                                              if_else(d$val < mean(d$val) - sd(d$val),
                                                      "#FEE7DA",
                                                      "transparent")))

kbl(d, escape = FALSE) %>%
  kable_styling()

Solution

  • The issue is that cell_spec only targets the cell content, i.e. the span tag which contains the content, but not the parent table cell, i.e. the td tag. And by default some padding of 8px is added to the content of the table cell.

    One option to fill the entire cell would be to use the extra_css= argument of cell_spec, i.e. set the margin to -8px and the padding to 8px so that the cell content fills the entire height of the cell. Additionally set display: flex to fill the entire width of the cell.

    library(kableExtra)
    
    set.seed(123)
    
    name <- paste("Name", LETTERS)
    val <- rnorm(26, 100, 50)
    d <- data.frame(name, val)
    
    d$val <- cell_spec(d$val,
      background = dplyr::case_when(
        d$val > mean(d$val) + sd(d$val) ~ "#DBEBF6",
        d$val < mean(d$val) - sd(d$val) ~ "#FEE7DA",
        .default = "transparent"
      ),
      extra_css = "margin: -8px; padding: 8px; display: flex;"
    )
    
    kbl(d, escape = FALSE) %>%
      kable_styling()
    

    enter image description here

    EDIT With display: flex we need some additional CSS to center align the values (see e.g. Aligning items in a flex container):

    d$val <- cell_spec(d$val,
      background = dplyr::case_when(
        d$val > mean(d$val) + sd(d$val) ~ "#DBEBF6",
        d$val < mean(d$val) - sd(d$val) ~ "#FEE7DA",
        .default = "transparent"
      ),
      extra_css = paste(
        "margin: -8px; padding: 8px;",
        "display: flex; align-items: center;",
        "justify-content: center;",
        sep = "; "
      )
    )
    
    kbl(d,
      align = c("l", "c"),
      escape = FALSE
    ) %>%
      kable_styling()
    

    enter image description here