glin/reactable

Heat map table displaying one table with color based on another

AnnaCalderon opened this issue · 1 comments

Hi,
I have been truing to create a table colored as a heatmap with reactable. However the way I am trying to create this is a little different. I would like to display the data from one table and color it based on another. Both tables have the same structure (same number of rows and columns), but one contains the count of a measure and the other it's rate.

This is how I am trying to create the table. It knits the html document and creates the table but it does not highlight the colors properly.

count_data |>   
  reactable(
    defaultColDef = colDef(
      style = color_scales(rate_data, span = 2:4, colors = my_color_pal))
    ) 

Please see Stackoverflow for code for more details:
https://stackoverflow.com/questions/77312840/heatmap-table-using-reactable-in-r

glin commented

Hi, so I wasn't able to run the code from the Stackoverflow post. I got an error and couldn't figure it out:

library(reactable)
library(reactablefmtr)

county <- c("Erie", "Orange", "Oneida")
jan <- c(8, 6, 5)
jul <- c(7, 3, 2)
dec <- c(17, 4, 6)
count_data <- data.frame(county, jan, jul, dec)

county <- c("Erie", "Orange", "Oneida")
jan <- c(0.36, 0.27, 0.21)
jul <- c(0.7, 0.30, 0.17)
dec <- c(0.81, 0.18, 0.26)
rate_data <- data.frame(county, jan, jul, dec)

my_color_pal = c('#e5f5e0', '#a1d99b', '#31a354', 'darkgreen')
#mypal = colorRampPalette(c("blue", "green", "yellow", "red"), bias = 0.5, space="Lab")

count_data |>   
  reactable(
    defaultColDef = colDef(
      style = color_scales(rate_data, span = 2:4, colors = my_color_pal)
    )
  ) |> 
  add_legend(
    data = rate_data,
    col_name = "dec",
    colors = my_color_pal,
    number_fmt = scales::percent_format(accuracy = 1L, scale = 1)
    # bin = 4
  )

# Error in rgb(colorRamp(c(colors), bias = bias)(x), maxColorValue = 255) : 
#  color intensity NA, not in 0:255

But I think I get the gist of it, so here's a different example. The general approach would be to use the index argument in the cell style function to find the corresponding value in a different table. This example is based on the Color Scales example from the docs.

Instead of a color scale for the Petal.Length column, I modified the table to conditionally color the Species column based on the Petal.Length values from a different table, data_colors.

library(reactable)

data <- iris[10:29, ]
orange_pal <- function(x) rgb(colorRamp(c("#ffe4cc", "#ff9500"))(x), maxColorValue = 255)

data_colors <- data

reactable(
  data,
  columns = list(
    Species = colDef(
      style = function(value_unused, index) {
        # Get the corresponding value for styling from the data_colors table,
        # using the row index. The value argument in the style function is unused
        # because we're using the value from a different table for styling instead.
        value <- data_colors[index, "Petal.Length"]
        normalized <- (value - min(data_colors$Petal.Length)) / (max(data_colors$Petal.Length) - min(data_colors$Petal.Length))
        color <- orange_pal(normalized)
        list(background = color)
      }
    )
  )
)