1

I am building a Shiny app in R to display multiple data frames, 6 in total on 1 Shiny page. I am able to conditional format 1 data table in Shiny, but I am unable to conditionally format all 6 tables. Each of the 6 tables have 5 variables and I want the 2nd variable in every data table: background light up red and bold if >= 75, and light up green and bold if <= 75:

library(shiny)
ui <- fluidPage(
  titlePanel("xxx"),
  title = 'xx',
  fluidRow(
column(6 
       , fluidRow(
          column(6, DT::dataTableOutput('1'), style = "font-size: 
              75%; width: 50%"),
          column(6, DT::dataTableOutput('2'), style = "font-size: 
             75%; width: 50%")
       ),
       # hr(),
       fluidRow(
           column(6, DT::dataTableOutput('3'), style = "font-size: 
              75%; width: 50%"),
            column(6, DT::dataTableOutput('4'), style = "font-size: 
               75%; width: 50%")
       ),
       # hr(),
       fluidRow(
            column(6, DT::dataTableOutput('5'), style = "font-size: 
                75%; width: 50%"),
            column(6, DT::dataTableOutput('6'), style = "font-size: 
                75%; width: 50%")
       )
      )
   server <- function(input, output) {
          output$1 = DT::renderDataTable(1
                   , server = FALSE, selection = 'single'
                   , options = list(rowCallback = JS('function(nRow
                   , aData, iDisplayIndex, iDisplayIndexFull) {
                    // Bold and green cells for conditions
                     if (parseFloat(aData[2]) 
                      >= 75 | parseFloat(aData[2]) <= -75)
                       $("td:eq(2)", nRow).css("font-weight", "bold");
                      if (parseFloat(aData[2]) >= 75)
                       $("td:eq(2)", nRow).css("background-color"
                         , "#FF0000");
                  else if(parseFloat(aData[2]) <= -75)
                        $("td:eq(2)", nRow).css("background-color", 
                           "#00FF00");
                   else 
                      $("td:eq(2)", nRow).css("background-color"
                      , "#FFFFFF");
                                  }'
                                    )
                        , drawCallback = JS()
                                  ))

      output$2 = DT::renderDataTable(2, server = FALSE, 
               selection = 'single')
      output$3 = DT::renderDataTable(3, server = FALSE, 
                selection = 'single')
      output$4 = DT::renderDataTable(4, server = FALSE, 
                selection = 'single')
      output$5 = DT::renderDataTable(5, server = FALSE, 
             selection = 'single')
      output$6 = DT::renderDataTable(6, server = FALSE, 
                 selection = 'single')
mrklkr
  • 11
  • 1
  • 1
    Please specify in detail what kind of problems arise. Your statement " I am unable to conditionally format all 6 tables" is too vague. – Omni Dec 20 '17 at 23:52
  • When I run this code it works for output$1 for conditionally formatting column 2, when I try to add the same code to output$2, nothing changes. output$1 stays conditionally formatted in column 2, but output$2 has no conditional formatting. I need to conditionally format all 6 data frames in column 2. Thank you for your help. – mrklkr Dec 21 '17 at 03:04
  • First of all you should not name DataTable Id`s as numbers, rather: Table1, Table2 ... – Mal_a Dec 21 '17 at 06:15

1 Answers1

1

I have tried Your code and it is working well for me, have a look below:

library(shiny)
library(DT)
ui <- fluidPage(
  titlePanel("xxx"),
  title = 'xx',
  fluidRow(
    column(12 
           , fluidRow(
             column(6, DT::dataTableOutput('Table1'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table2'), style = "font-size: 
                    75%; width: 50%")
             ),
           # hr(),
           fluidRow(
             column(6, DT::dataTableOutput('Table3'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table4'), style = "font-size: 
                    75%; width: 50%")
             ),
           # hr(),
           fluidRow(
             column(6, DT::dataTableOutput('Table5'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table6'), style = "font-size: 
                    75%; width: 50%")
             )
             )))
    server <- function(input, output) {
      output$Table1 = DT::renderDataTable(mtcars
                                     , server = FALSE, selection = 'single'
                                     , options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                       // Bold and green cells for conditions
                                                                       if (parseFloat(aData[2]) 
                                                                       >= 1 | parseFloat(aData[2]) <= 3)
                                                                       $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                       if (parseFloat(aData[2]) >= 1)
                                                                       $("td:eq(2)", nRow).css("background-color"
                                                                       , "#FF0000");
                                                                       else if(parseFloat(aData[2]) <= 3)
                                                                       $("td:eq(2)", nRow).css("background-color", 
                                                                       "#00FF00");
                                                                       else 
                                                                       $("td:eq(2)", nRow).css("background-color"
                                                                       , "#FFFFFF");
                                                                       }'
                                    )))

      output$Table2 = DT::renderDataTable(iris, server = FALSE, 
                                     selection = 'single', options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                                           // Bold and green cells for conditions
                                                                                           if (parseFloat(aData[2]) 
                                                                                           >= 1 | parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                                           if (parseFloat(aData[2]) >= 1)
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FF0000");
                                                                                           else if(parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("background-color", 
                                                                                           "#00FF00");
                                                                                           else 
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FFFFFF");
    }'
                                    )))
      output$Table3 = DT::renderDataTable(iris, server = FALSE, 
                                     selection = 'single', options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                                           // Bold and green cells for conditions
                                                                                           if (parseFloat(aData[2]) 
                                                                                           >= 1 | parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                                           if (parseFloat(aData[2]) >= 1)
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FF0000");
                                                                                           else if(parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("background-color", 
                                                                                           "#00FF00");
                                                                                           else 
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FFFFFF");
    }'
                                    )))
      output$Table4 = DT::renderDataTable(iris, server = FALSE, 
                                     selection = 'single', options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                       // Bold and green cells for conditions
                                                                       if (parseFloat(aData[2]) 
                                                                       >= 1 | parseFloat(aData[2]) <= 3)
                                                                       $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                       if (parseFloat(aData[2]) >= 1)
                                                                       $("td:eq(2)", nRow).css("background-color"
                                                                       , "#FF0000");
                                                                       else if(parseFloat(aData[2]) <= 3)
                                                                       $("td:eq(2)", nRow).css("background-color", 
                                                                       "#00FF00");
                                                                       else 
                                                                       $("td:eq(2)", nRow).css("background-color"
                                                                       , "#FFFFFF");
                                                                       }'
                                     )))
      output$Table5 = DT::renderDataTable(iris, server = FALSE, 
                                     selection = 'single', options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                                           // Bold and green cells for conditions
                                                                                           if (parseFloat(aData[2]) 
                                                                                           >= 1 | parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                                           if (parseFloat(aData[2]) >= 1)
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FF0000");
                                                                                           else if(parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("background-color", 
                                                                                           "#00FF00");
                                                                                           else 
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FFFFFF");
    }'
                                    )))
      output$Table6 = DT::renderDataTable(iris, server = FALSE, 
                                     selection = 'single', options = list(rowCallback = JS('function(nRow
                                                                       , aData, iDisplayIndex, iDisplayIndexFull) {
                                                                                           // Bold and green cells for conditions
                                                                                           if (parseFloat(aData[2]) 
                                                                                           >= 1 | parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("font-weight", "bold");
                                                                                           if (parseFloat(aData[2]) >= 1)
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FF0000");
                                                                                           else if(parseFloat(aData[2]) <= 3)
                                                                                           $("td:eq(2)", nRow).css("background-color", 
                                                                                           "#00FF00");
                                                                                           else 
                                                                                           $("td:eq(2)", nRow).css("background-color"
                                                                                           , "#FFFFFF");
    }'
                                    )))}
shinyApp(ui, server)

Every Table got column highlighted as You wanted.

--> I have just changed the Id of DataTable, read DT library and corrected Your brackets.

In Your case i would consider to format an entire column without JS with help of formatStyle().

Please next time post a reproducible example.

[UPDATE] Solution with formatStyle()

Below You can see the solution using formatStyle() option, comments to the code are just next to the specific lines.

library(shiny)
library(DT)
ui <- fluidPage(
  titlePanel("xxx"),
  title = 'xx',
  fluidRow(
    column(12 
           , fluidRow(
             column(6, DT::dataTableOutput('Table1'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table2'), style = "font-size: 
                    75%; width: 50%")
             ),
           # hr(),
           fluidRow(
             column(6, DT::dataTableOutput('Table3'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table4'), style = "font-size: 
                    75%; width: 50%")
             ),
           # hr(),
           fluidRow(
             column(6, DT::dataTableOutput('Table5'), style = "font-size: 
                    75%; width: 50%"),
             column(6, DT::dataTableOutput('Table6'), style = "font-size: 
                    75%; width: 50%")
             )
             )))
server <- function(input, output) {
  output$Table1 = DT::renderDataTable(
    datatable(mtcars) %>% 
      formatStyle('cyl', fontWeight = styleInterval(4, c('normal', 'bold')), # Font bold if cyl > 4
                  backgroundColor = styleInterval(4, c('green', 'red'))) # Red background if cyl > 4
  )

}
shinyApp(ui, server)
Mal_a
  • 3,670
  • 1
  • 27
  • 60
  • Thank you so much. I would rather use formatStyle(), I just couldn't get it to work. Any suggestions would be so so helpful. Thank you! – mrklkr Dec 21 '17 at 13:34
  • My code now works, however, I would rather use formatsyle. In addition, what if I wanted to create a plot so if I "clicked" in any of the 6 data tables a plot would come up of the data. – mrklkr Dec 21 '17 at 16:04