Search code examples
rshinyconditional-formattingdthtmlwidgets

Formatting DT::datatables based on logical vector


I currently want to use colorformatting for my dataFrames using shiny and the DT package. My table looks roughly like this.

| val1     | val2  | 
| ---------|------ |
| a        | b     |
| a        | a     |
| b        | b     |

I want to change the textcolor of val1 as red whenever val1[i] == val2[i] is satisfied. So the resulting table should look like this.

| val1     | val2  | 
| ---------|------ |
| a        | b     |
| a*       | a     |    * = red
| b*       | b     |

From the documentation, I see that conditional formatting can be applied with DT::formatstyle. However, the conditions specified there must be dependent on one single column of the table. Of course, I could create a new column with

dat$condition = ( val1 == val2 )

but then this column is also displayed in the widget which I don't want to happen. (Unless there is a way of removing columns of datatables objects). I am looking for a function addcolor_conditional that does something like this

condition_vector = ( val1 == val2 )
datatable( mtcars ) %>% addcolor_conditional( 
  condition_vector, color = "red" )

Any help would be appreciated


Solution

  • You can use the rowCallback argument and a little js code to do that. Have a look at the following minimal code:

    library(shiny)
     library(DT)
     
     
     data_ <- data.frame(A = 1:5, B=c(1,3,6,4,5))
     
     ui <- fluidPage(
       
       
       dataTableOutput("table")
     )
    
     server <- function(input, output){
       
       output$table <- renderDataTable({
        datatable(data_, rownames = FALSE, options = list(rowCallback = JS(
                         "function(nRow, aData) {
                         if (parseFloat(aData[0]) >= parseFloat(aData[1])){
                         $('td:eq(0)', nRow).css('color', 'red');
                         }
                         }")
                       ))
         
         
       }) 
       
     }
     
     shinyApp(ui = ui, server = server)
    

    The output that you get using the code is as follows:

    enter image description here

    Hope it helps!