0

Consider the following table using the reactable and reactablefmtr packages:

library(reactable)
library(reactablefmtr)

my_color_pal <- c("white", "red")

df <- head(mtcars[,"mpg", drop = FALSE])

reactable(
  df,
  columns = list(
    mpg = colDef(style = color_scales(df, colors = my_color_pal))
  )
)

I get this:

reactable output from code

Instead of using the current range of the mpg column, I want to set the 'domain' of the color scales where values close to zero are white and values close to 100 are red.

David Ranzolin
  • 913
  • 1
  • 6
  • 18

1 Answers1

1

One option would be to use e.g. scales:: col_numeric to create a palette function for your desired domain. This function could then be used to add a column of colors to your dataset which could then be used to color the table cells via the color_ref argument of color_scales:

library(reactable)
library(reactablefmtr)

my_color_pal <- c("white", "red")

df <- head(mtcars[, "mpg", drop = FALSE])

pal_color <- scales::col_numeric(my_color_pal, c(0, 100))
df$color <- pal_color(df$mpg)

reactable(
  df[, "mpg", drop = FALSE],
  columns = list(
    mpg = colDef(style = color_scales(df, color_ref = "color"))
  )
)

EDIT A second option to achieve the desired result would be to use a custom color scale function which following the Conditional Styling vignette could be implemented like so:

pal_color <- function(x) rgb(colorRamp(my_color_pal, space = "Lab")(x), maxColorValue = 255)

my_color_scale <- function(value, ..., domain = c(0, 100)) {
  normalized <- (value - domain[[1]]) / diff(range(domain))
  color <- pal_color(normalized)
  list(background = color)
}

reactable(
  df[, "mpg", drop = FALSE],
  columns = list(
    mpg = colDef(style = my_color_scale)
  )
)
stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thanks @stefan, this solves my example and I'll mark it as the solution. But what if: (1) I also select the cyl column and add it as the groupBy argument in reactable(), e.g. reactable(df, groupBy = "cyl"); and (2) I add colDef(aggregate = "mean")? The aggregate values do not get colored this way. – David Ranzolin Mar 17 '23 at 15:45
  • 1
    Hm. That becomes tricky. First, even in the example from your question the group aggregates won't get colored. To achieve that we need a custom JS render. See https://github.com/glin/reactable/issues/200#issuecomment-933008684. I can only imagine that following this approach we could do some kind of interpolation to assign colors to the group aggregates based on the values in the color column. BTW: During my research on this topic I came up with a second approach using a custom color scale function. See my edit. – stefan Mar 17 '23 at 16:33