Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DT in Shiny: Change only the colour of a single row

Tags:

r

dt

shiny

I have a dataset:

ID Value
102 306
41  800
101 783
105 193
myID 334

I would like to draw this up as a datatable where only the row with 'myID' is coloured orange and the rest of the table is blue. Having looked at the helper functions and other examples, it seems that I should be using styleEqual. However, I don't know what the values in my other rows are, and also they will change dynamically.

I tried using

datatable(tableData) %>%
formatStyle(0, target= 'row',color = 'black', backgroundColor = tableColour, 
                lineHeight='70%', padding = '3px 3px', fontSize = '80%') %>%
    formatStyle('ID', target = 'row', 
    backgroundColor = styleEqual(c("myID"), c('orange')))

However, this does not work - the whole table is blue, and the second formatStyle statement is ignored. If I remove the first formatStyle, I get my row coloured in orange but lose all other formatting. Is there a way to use styleEqual to define e.g. c("myID", "All other IDs"), or is there another workaround?

like image 757
Hester Lyons Avatar asked Mar 08 '18 14:03

Hester Lyons


2 Answers

If you want to use DT you can use styleEqual() to add background color to your table if the condition is met. There does not seem to be an else option, so you can create an object of class JS_EVAL (which would be returned by styleEqual()) and add a negation:

background <- "value == 'myID' ? 'orange' : value != 'else' ? 'blue' : ''"  
class(background) <- "JS_EVAL"

datatable(tableData) %>% formatStyle(
  'ID',
  target = 'row',
  backgroundColor = background
)

The result looks like this:

enter image description here

You could also achieve it using the package tableHTML:

library(tableHTML)

tableData %>% 
  tableHTML(rownames = FALSE,
            widths = c(100, 100)) %>% 
  add_css_row(rows = which(tableData$ID == 'myID') + 1,
              css = list(c("background-color"),
                         c("orange"))) %>% 
  add_css_row(rows = which(tableData$ID != 'myID') + 1,
              css = list(c("background-color"),
                         c("blue")))

The result looks like this:

enter image description here

like image 155
clemens Avatar answered Sep 22 '22 13:09

clemens


I can think of two possible workarounds:

  • Create a helper column that is 1 or 0, based on if your column is equal to myID or not, then use that column to style the table and hide that column.
  • Create a column mapping for all your unique values in the column ID, that defaults to a certain color, and set only the value corresponding to myID to orange.

A working example of the second option is given below. Hope this helps!


enter image description here

df = read.table(text='ID Value
102 306
41  800
101 783
105 193
myID 334',header=T)

library(DT)

my_vals = unique(df$ID)
my_colors = ifelse(my_vals=='myID','orange','grey')

datatable(df) %>%
  formatStyle('ID', target = 'row', 
              backgroundColor = styleEqual(my_vals,my_colors))
like image 20
Florian Avatar answered Sep 24 '22 13:09

Florian