0

With code below (from this link), we can set background colors for the cells of multiple columns based on string contents using gt package:

library(gt)
library(tidyverse)

id <- c(1,2,3,4,5)
res1 <- c("true", "true", "false", "true", "false")
res2 <- c("false", NA, NA, "true", "true")
df <- data.frame(id, res1, res2)

df %>% 
  gt() %>% 
  data_color(
    columns = c("res1", "res2"),
    colors = c("green", "red"),
    apply_to = "fill",
    autocolor_text = FALSE)

Out:

enter image description here

Now let's say I will need to set red background color only if content is true for columns res1 and res2, if it's other values such as false or NA, just keep as original, which means I hope to highlight true cells for these two columns. How could I do that? Thanks.

References:

https://gt.rstudio.com/reference/tab_style.html

ah bon
  • 9,293
  • 12
  • 65
  • 148

1 Answers1

2

Using gt::tab_style you could do:

library(gt)
library(magrittr)

df %>% 
  gt() %>% 
  tab_style(
    style = list(
      cell_fill(color = "red")
    ),
    locations = cells_body(
      columns = c(res1, res2),
      rows = res1 == "true" & res2 == "true"
    )
  )

enter image description here

EDIT In case of multiple columns you could basically create the conditions like so. Basic idea it to first create a string containing the condition on which rows to target and using !!rlang::parse_expr to evaluate that string inside gt::cell_body:

Note: I added two more columns to your df to make the example more realistic.

library(gt)
library(magrittr)

df <- data.frame(id, res1, res2, res3 = res1, res4 = res2)


cols <- paste0("res", 1:4)
conditions <- lapply(cols, function(x) "true")
names(conditions) <- cols 

rows <- paste(glue::glue("{.col} == '{.value}'", .col = names(conditions), .value = conditions), collapse = " & ")

df %>%
  gt() %>%
  tab_style(
    style = list(
      cell_fill(color = "red")
    ),
    locations = cells_body(
      columns = all_of(cols),
      rows = !!rlang::parse_expr(rows)
    )
  )

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Yes, thanks for sharing this solution, but there is one issue, if I have a dataframe with many columns (20 columns for example) rather than only 2 columns, `rows = ` will be followed by the code very long. – ah bon Jan 29 '22 at 11:11
  • I See. Will have a look. I would guess that it should be possible to simplify that. – stefan Jan 29 '22 at 11:20
  • I just made an edit to show you one possible option. – stefan Jan 29 '22 at 11:39