bodega18
bodega18

Reputation: 654

Coloring Formattable Data Table in R - Stock Data

I have a datatable storing the daily/weekly/monthly returns for several stocks that I am trying to color with R's formattable package. I want negative returns to be red, and positive returns to be green. Or to get fancy, have a separate gradient for positive and negative values - so if Apple was down 10% for a day it would be dark red, and if Amazon was down 2%, that cell would be a lighter red - and vice versa for positive returns (light and dark green).

My issue is that when I use a red-green gradient, the colors in the middle appear brown-ish colored. The code I have below has transparent/white as the low end of the gradient, and green as the upper end, but is pretty tough to differentiate.

My datatable looks something like:

Stock day  week   month
AAPL   1.5  3.2   10.6
AMZN   3.2  5.3   4.4
BA    -2.1 -4.0  -10.5
PYPL   -5  -8.5  -12.1



Green <- "#71ca99"

sign_formatter <- formatter("span", 
                            style = x ~ style(color = ifelse(x > 0, "green", 
                                                             ifelse(x < 0, "red", "black"))))
sign_formatter(c(-1, 0, 1))

returns <- formattable(stocks_df, align =c("l","c","c","c","c"), list(
  `Stock` = formatter("span", style = ~ style(color = "grey",font.weight = "bold")), 
  daily_return = color_tile("transparent", Green),
  week_return = color_tile("transparent", Green),
  month_return = color_tile("transparent", Green)))

@dc37

I am using the exact code you suggested - the colors are working perfectly. But when I sort by weekly return like in the example below, to get stocks with the best performance for the week, it is not sorting highest to lowest (having the same issue when I try to sort by worst performing stocks).

Here is a picture of what my formattable output looks like. I am also running this in Shiny, not sure if that is what could be throwing the error with sorting.

enter image description here

Upvotes: 2

Views: 2821

Answers (1)

dc37
dc37

Reputation: 16178

A possible solution will be to create multiple ifelse statement in order to set 5 different colors (red / lightred / white / lightgreen / green) in function of the value of each columns.

Here, a possible way of doing it:

Test <- formatter("span",
                  style = x ~ style(display = "block", font.weight = "bold",color = "black","border-radius" = "4px",
                                 "padding-right" = "4px",
                                 "background-color" = ifelse(x <= -10, "red", ifelse(x > -10 & x <= -2, "tomato", ifelse(x > -2 & x <= 2, "white", ifelse(x > 2 & x <= 10, "palegreen",ifelse(x > 10, "green",NA)))))),
                  x ~ percent(x/100))

formattable(stocks_df,align =c("l","c","c","c","c"), list(
  `Stock` = formatter("span", style = ~ style(color = "grey",font.weight = "bold")),
  day = Test,
  week = Test, 
  month = Test))

enter image description here

Does it answer your question ?

Reproducible example

structure(list(Stock = c("AAPL", "AMZN", "BA", "PYPL"), day = c(1.5, 
3.2, -2.1, -5), week = c(3.2, 5.3, -4, -8.5), month = c(10.6, 
4.4, -10.5, -12.1)), row.names = c(NA, -4L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x55b7eeb735c0>)

Upvotes: 6

Related Questions