Search code examples
rgt

Color out of bounds values with nearest color in {gt}


I am encountering an issue with the gt package in R while trying to colorize a dataframe based on specific value ranges. I have a dataframe df with columns 'a' and 'b', and I want values above 15 to be displayed in red and values below 11 in green. However, the current code doesn't seem to produce the expected result.

library(gt)
library(dplyr)

df <- data.frame(a = 1:21, b = rep(10:30))

df %>%
  gt() %>%
  gt::data_color(
    colors = scales::col_numeric(
      # na.color = "green",
      palette = c("green", "red"),
      domain = c(11, 15)
    )
  )

The issue is that the na.color = "green" parameter is affecting the coloration of values above 15. I would like to correct this behavior and have values above 15 displayed in red, and bellow 11 in green.

edit : I need to keep the gradient from green to red between 11 and 14

enter image description here

thanks to @mael here is a working solution

pal <- function(x,bin=c(11,15),palette = c("green", "red")) {
  f1 <- scales::col_bin(
    palette = palette[1],
    bin = c(-Inf, bin[1])
  )
  f2 <- scales::col_numeric(
    palette = palette,
    domain = c(bin[1], bin[2])
  )
  f3 <- scales::col_bin(
    palette = palette[2],
    bin = c(bin[2], Inf)
  )
  
  dplyr::case_when(
    x < bin[1] ~ f1(x),
    x < bin[2] ~ f2(x),
    x < Inf ~ f3(x)
  )
}
df %>%
gt() %>%
gt::data_color(fn = pal)

Solution

  • Edit:

    After some research, one option could be to use scales::oob_squish (as used in ggplot2) but I was not able to make it work (might be a relevant feature request), so you might be stuck with creating a custom function, like so. This was inspired from this answer:

    pal <- function(x) {
      f1 <- scales::col_bin(
        palette = "green",
        bin = c(-Inf, 11)
      )
      f2 <- scales::col_numeric(
        palette = c("green", "red"),
        domain = c(11, 15)
      )
      f3 <- scales::col_bin(
        palette = "red",
        bin = c(15, Inf)
      )
    
      dplyr::case_when(
        x < 11 ~ f1(x),
        x < 15 ~ f2(x),
        x < Inf ~ f3(x)
      )
    }
    
    df %>%
      gt() %>%
      gt::data_color(fn = pal)
    

    enter image description here