如何使用gt根据多列中的(字符,NA)内容自定义背景颜色

How to customize background colors based on (characters, NA) contents in multiple columns using gt

基于中的代码和数据,我们可以使用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")
res3 <- c("true", NA, NA, "true", "true")
df <- data.frame(id, res1, res2, res3)

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

但是您可能已经注意到,对于 res3true 的颜色是 green 而不是其他两列中的 red。如果我希望为true设置redfalse设置greenNA设置gray,对于这3列,如果以防万一,它们还有其他值,例如yesno等,保持原样即可。

我们如何解决这个问题?非常感谢。

Update1: tab_style() 的替代解决方案,但不简洁:

df %>% 
  gt() %>% 
  tab_style(
    style = list(
      cell_fill(color = 'red')
    ),
    locations = cells_body(
      columns = res1,
      rows = res1 == "true"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'red')
    ),
    locations = cells_body(
      columns = res2,
      rows = res2 == "true"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'red')
    ),
    locations = cells_body(
      columns = res3,
      rows = res3 == "true"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'green')
    ),
    locations = cells_body(
      columns = res1,
      rows = res1 == "false"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'green')
    ),
    locations = cells_body(
      columns = res2,
      rows = res2 == "false"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'green')
    ),
    locations = cells_body(
      columns = res3,
      rows = res3 == "false"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'gray')
    ),
    locations = cells_body(
      columns = res1,
      rows = res1 == NA
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'gray')
    ),
    locations = cells_body(
      columns = res2,
      rows = res2 == NA
    )
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = 'gray')
    ),
    locations = cells_body(
      columns = res3,
      rows = res3 == NA
    )
  )

更新2:如何正确设置NA单元格的灰色?

cols <- c('res1', 'res2', 'res3')
df %>% 
  # mutate_each_(funs(factor(.)), cols)
  mutate_at(cols, factor) %>% 
  gt() %>% 
  data_color(
    columns = cols,
    colors = scales::col_factor(
      palette = c('green', 'red', 'gray'),
      domain = c('false', 'true', NA)
    ),
    apply_to = "fill",
    autocolor_text = FALSE
  )

Update3:我设置了palette = c("green", "red", 'yellow'), domain = c("false", "true", '-'),为什么false不显示green,[=16=red =],yellow -?

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

df %>% 
  mutate_at(cols, factor) %>% 
  gt() %>% 
  data_color(
    columns = cols,
    colors = scales::col_factor(
      palette = c("green", "red", 'yellow'),
      domain = c("false", "true", '-'),
      na.color = 'gray'
    ),
    apply_to = "fill",
    autocolor_text = FALSE
  )

参考文献:

将逻辑值存储为字符串不是一个好主意。如果您改用 TRUEFALSE 值,gt() 会按照设计为您提供所需的 table 颜色。

id <- c(1,2,3,4,5)
res1 <- c(TRUE, TRUE, FALSE, TRUE, FALSE)
res2 <- c(FALSE, NA, NA, TRUE, TRUE)
res3 <- c(TRUE, NA, NA, TRUE, TRUE)
df2 <- data.frame(id, res1, res2, res3)

df2 %>% 
  gt() %>% 
  data_color(
    columns = c(res1, res2, res3),
    colors = scales::col_factor(
      palette = c("green", "red"),
      domain = c(FALSE, TRUE)
    ),
    apply_to = "fill",
    autocolor_text = FALSE
  )

如果出于某种原因您必须将逻辑作为字符串,您需要将它们转换为一个因子并调整 data_color() 中的 domain 参数。

关于Update 2,带字符串的版本,应该可以:

df %>% 
  mutate_at(cols, factor) %>% 
  gt() %>% 
  data_color(
    columns = cols,
    colors = scales::col_factor(
      palette = c("green", "red"),
      domain = c("false", "true")
    ),
    apply_to = "fill",
    autocolor_text = FALSE
  )