Is it possible to use more than 2 colors in the color_tile function?

前端 未结 5 927
青春惊慌失措
青春惊慌失措 2020-12-12 01:29

I have a dataframe column that I\'m currently formatting using the formattable::color_tile function (below):

color_tile( \"red\", \"springgreen\"

相关标签:
5条回答
  • 2020-12-12 01:57

    In an issue' entry of the github' formattable site, I found this which seems useful and solved my problem to have a column color coded on continuous scale from negative to positive as red to green, without having the "brown" in the middle (this will deliver "transparent"):

    library(dplyr)
    library(kableExtra)
    library(formattable)
    
    x = currency(c(1000000,
                     -3000,
                    400000,
                    800000,
                     -1700,
                         0,
                     50000))
    
    x = ifelse(
      x <= 0.0, 
      color_tile("red", "transparent")(x*c(x<=0)),
      color_tile("transparent", "green")(x*c(x>=0)))
    
    x %>% 
      kable(escape = F) %>% 
      kable_styling(bootstrap_options = c("striped", "hover"), 
                    full_width = F)
    

    This is the relevant link: https://github.com/renkun-ken/formattable/issues/102#issuecomment-408649019

    0 讨论(0)
  • 2020-12-12 01:57

    Something like this might work, leveraging RColorBrewer

    color_tile3 <- function(fun = "comma", digits = 0, palette = 'RdBu', n = 9) {
      fun <- match.fun(fun)
    
      stopifnot(n >= 5)
      
      return_cut <- function(y) 
        cut(y, breaks = quantile(y, probs = 0:n/n, na.rm = T),
            labels = 1:n, ordered_result = T, include.lowest = T)
      
      return_col <- function(y) 
          RColorBrewer::brewer.pal(n, palette)[as.integer(return_cut(y))]
      
      formatter("span", x ~ fun(x, digits = digits),
                style = function(y) style(
                  display = "block",
                  padding = "0 4px",
                  "border-radius" = "4px",
                  "color" = ifelse( return_cut(y) %in% c(1, 2, n-1, n),
                                    csscolor("white"), csscolor("black")),
                  "background-color" = return_col(y)
                )
      )
    }
    

    Use case:

    library(tidyverse)
    library(RColorBrewer)
    
    mtcars[, 1:5] %>%
      corrr::correlate() %>%
      formattable(., list(
        `rowname` = formatter("span", style = ~ style(color = "grey", 
                                                      font.weight = "bold")), 
        area(col = 2:6) ~ color_tile3(digits = 2)))
    

    mtcars_color3

    I can't embed yet, but here's a link to the output

    0 讨论(0)
  • 2020-12-12 01:58

    Based on @cmilando, I rewrite the function so that the colors reflect negative and positive numbers better, a bit manually though :D

    library(tidyverse)
    library(RColorBrewer)
    library(formattable)
    library(kableExtra)
    library(purrr)
    
    # --------------------
    # brewer.pal(10,"RdYlGn")
    
    my_color_tile <- function() {
      
      return_col <- function(y) 
        map_chr(y,function(x) case_when(x > 80  ~ "#006837",
                  x > 60  ~ "#1A9850",
                  x > 40  ~ "#66BD63",
                  x > 20  ~ "#A6D96A",
                  x >= 0  ~ "#D9EF8B",
                  x >= -20  ~ "#FEE08B",
                  x >= -40  ~ "#FDAE61",
                  x >= -60  ~ "#F46D43",
                  x >= -80  ~ "#D73027",
                  x >= -100  ~ "#A50026"
                  ))
      
      formatter("span", 
                style = function(y) style(
                  display = "block",
                  padding = "0 4px",
                  "border-radius" = "4px",
                  "color" = ifelse( return_col(y) %in% c("#A50026","#D73027","#F46D43","#006837","#1A9850","#66BD63"),
                                    csscolor("white"), csscolor("black")),
                  "background-color" = return_col(y)
                )
      )
    }
    
    # --------------------
    data.frame(value = c(seq(-100,100,10))) %>% 
      arrange(desc(value)) %>%  
      formattable(., list(
        area(col = 1) ~ my_color_tile()))
    
    
    0 讨论(0)
  • 2020-12-12 01:59

    It doesn't look like the function is designed to handle more than two colors, but you can make your own building on that template.

    color_tile2 <- function (...) {
      formatter("span", style = function(x) {
        style(display = "block",
              padding = "0 4px", 
              `border-radius` = "4px", 
              `background-color` = csscolor(matrix(as.integer(colorRamp(...)(normalize(as.numeric(x)))), 
                                                   byrow=TRUE, dimnames=list(c("red","green","blue"), NULL), nrow=3)))
      })}
    

    which can be used like

    formattable(mtcars, list(mpg = color_tile2(c("white", "pink"))))
    formattable(mtcars, list(mpg = color_tile2(c("blue", "green", "pink"))))
    
    0 讨论(0)
  • 2020-12-12 02:06

    Determine which row numbers you want between color 1 and 2 and which row numbers for between color 2 and 3. Then call color_tile twice. For example

    formattable(x, 
            list(
              area(col = 2, row = c(1,3,5,7,8,9,10,13,14,15)) ~ color_tile("red", "white"),
              area(col = 2, row = c(2,4,6,11,12,16)) ~ color_tile("white","green")
            ))
    

    Won't fix it perfectly, since it won't keep the relative intensity of the colors on either side

    0 讨论(0)
提交回复
热议问题