Search code examples
rdplyrnagtcolor-palette

Make NA transparent when using a color palette-function


This is my dataframe:

Test = structure(list(Corr_p = c(0.65, 0.64, 0.64, NA, 0.79, 0.77), 
                      Case_p = c(24.57, 12.89, 20.92, NA, 11.1, 12.2), 
                      Control_p = c(16.4, 9.38, 16.21, NA, 7, 6.17), 
                      Delta_p = c(49.82, 37.42, 29.06, NA, 58.57, 97.73)), 
                 row.names = 18:23, class = "data.frame")

I defined a color-palette, one for column Delta_p and one for Corr_p

library(gt)
pal <- function(x) {
  f_neg <- scales::col_numeric(
    palette = c(emerald),
    domain = c(min(test, na.rm = TRUE), 0)
  )
  f_pos1 <- scales::col_numeric(
    palette = c(oryel),
    domain = c(0, 300)
  )
  f_pos2 <- scales::col_numeric(
    palette = c(sunshort),
    domain = c(300, 500)
  )
  f_pos3 <- scales::col_numeric(
    palette = c(toplevel),
    domain = c(500, max(test, na.rm = TRUE))
  )
  
  dplyr::case_when(
    x < 0 ~ f_neg(x),
    x < 300 ~ f_pos1(x),
    x < 500 ~ f_pos2(x),
    .default = f_pos3(x)
  )
}

library(scales)
corr_palette_pos <- col_numeric(c("#FEF0D9", "#990000"), domain = c(min_cor_pos, max_cor_pos), alpha = 0.75)

Then I plot the table. As you can see its using the default color for the NA values.

Test %>%
  gt() %>% 
  data_color(columns = c(Delta_p), colors = pal) %>%
  data_color(columns = c(Corr_p), colors = corr_palette_pos) 

enter image description here

But I want it to be transparent or white, just like the backround. I found so many examples: R gt table make NA values not appear

data_color(
    columns = colnames(df)[grep("res", colnames(df))],
    colors = scales::col_numeric(
      palette = pal,
      domain = c(0, 20),
      na.color = "transparent"
    )
  ) %>%

But when I use it like:

Test %>%
  gt() %>% 
  data_color(columns = c(Delta_p), colors = scales::col_numeric(palette = pal,
                                                                domain = c(29.06,97.73), 
                                                                na.color = "transparent")) %>%
  data_color(columns = c(Corr_p), colors = corr_palette_pos) 

All of the values are in the same color:

enter image description here

Any idea please, how to solve that problem? My thought is that I have to define that somehow in the pal-function?!

UPDATE

PS: Really nobody that could help?

Set asymmetric midpoint for data_color in gt table In this topic there is a comment on how to change the NA-Color within a if-else-Statement. I tried to implement it in the case-when-Statement, but I was not successful. I think that its the right spot to change it, but I just dont know how.

ifelse(x < 0 | is.na(x), f_neg(x), f_pos(x))

Solution

  • You have two palettes, pal and corr_palette_pos. In both, you need to specify how to handle NAs.

    • In pal, add is.na(x) ~ "transparent" to the case_when.
    • In corr_palette_pos, specify na.color = "transparent". Note that you can use domain = NULL to have the domain inferred from the data.
    library(gt)
    library(scales)
    
    emerald = c("#d3f2a3","#97e196","#6cc08b","#4c9b82","#217a79","#105965","#074050")
    oryel = c("#ecda9a","#efc47e","#f3ad6a","#f7945d","#f97b57","#f66356","#ee4d5a")
    sunshort = c("#dc3977","#b9257a","#7c1d6f")
    toplevel = c("#6c2167", "#541f3f")
    
    Test = structure(list(Corr_p = c(0.65, 0.64, 0.64, NA, 0.79, 0.77), 
                          Case_p = c(24.57, 12.89, 20.92, NA, 11.1, 12.2), 
                          Control_p = c(16.4, 9.38, 16.21, NA, 7, 6.17), 
                          Delta_p = c(49.82, 37.42, 29.06, NA, 58.57, 97.73)), 
                     row.names = 18:23, class = "data.frame")
    
    pal <- function(x) {
      f_neg <- col_numeric(
        palette = emerald,
        domain = c(min(Test, na.rm = TRUE), 0)
      )
      f_pos1 <- col_numeric(
        palette = oryel,
        domain = c(0, 300)
      )
      f_pos2 <- col_numeric(
        palette = sunshort,
        domain = c(300, 500)
      )
      f_pos3 <- col_numeric(
        palette = toplevel,
        domain = c(500, max(Test, na.rm = TRUE))
      )
      
      dplyr::case_when(
        x < 0 ~ f_neg(x),
        x < 300 ~ f_pos1(x),
        x < 500 ~ f_pos2(x),
        is.na(x) ~ "transparent",
        .default = f_pos3(x)
      )
    }
    
    corr_palette_pos <- col_numeric(
      c("#FEF0D9", "#990000"),
      domain = NULL,
      alpha = 0.75,
      na.color = "transparent"
    )
    
    Test %>%
      gt() %>% 
      data_color(columns = Delta_p, colors = pal) %>%
      data_color(columns = Corr_p, colors = corr_palette_pos) 
    

    image