5

I am trying to recreate a simple table from 538 using the gt package. I want to use 0 as the midpoint of the domain of the color scale and set that to white but 0 is not the midpoint of the actual domain.

df <- tribble(
  ~SEASON, ~ACC, ~BIG_10, ~BIG_12, ~PAC_12, ~SEC,
  2019, .02, -.05, 0, .02, .04,
  2018, -.06, .07, .07, .02, .01,
  2017, .05, -.04, .06, .16, .04,
  2016, 0, .05, -.04, -.02, .07,
  2015, .06, -.04, -.03, .01, .06,
  2014, .04, .05, .14, -.01, .06
)

This is what I have attempted to do:

gt(df) %>%
  data_color(
    columns = 2:6,
    colors = scales::col_numeric(
      palette = c('#feb8cd', '#ffffff', '#69cfd5'),
      domain = c(-.06,0, .16)
    )
  )

Table

This does not set the midpoint of the scale as values such as 0.04 are still slightly red/pink. I want those to be blue. I basically want two domains, the negative values (red to white) and positive values (white to blue) is there a way to do this?

1 Answers1

4

It looks like scales::col_numeric doesn't look at the individual domain values - it just gets the range and divides it evenly.

You can create your own function which calls one of two col_numeric functions.

pal <- function(x) {
  f_neg <- scales::col_numeric(
    palette = c('#feb8cd', '#ffffff'),
    domain = c(-.06, 0)
  )
  f_pos <- scales::col_numeric(
    palette = c('#ffffff', '#69cfd5'),
    domain = c(0, 0.16)
  )
  ifelse(x < 0, f_neg(x), f_pos(x))
}

gt(df) %>%
  data_color(columns = 2:6, colors = pal)

image

Paul
  • 8,734
  • 1
  • 26
  • 36
  • 1
    If you have NA values, I found this to be a good solution: ```ifelse(x < 0 | is.na(x), f_neg(x), f_pos(x))``` Essentially giving the negative color palette to account for the NAs. You can also explicitly change the default NA color by ```na.color = "#808080"``` changing that in f_neg. – Jas Sep 07 '22 at 05:58
  • 1
    This solution works but throws lots of warning messages highlighting that values are out of range because f_neg and f_pos are called for all x, and ifelse only used afterwards to select the items. To get rid of the warnings, I would wrap the whole function into Vectorise() – Lukas Wallrich Nov 15 '22 at 16:51
  • @Lukas Wallrich I know this question is old, but I have a very similar request and cant find a solution for it. Could you please have a look here: https://stackoverflow.com/questions/75710861/make-na-transparent-when-using-a-color-palette-function – Essi Mar 15 '23 at 11:46