【问题标题】:conditional format multiple tables in Shiny RShiny R中的条件格式多个表
【发布时间】:2018-06-03 14:20:20
【问题描述】:

我正在 R 中构建一个闪亮的应用程序来显示多个数据帧,在 1 个闪亮的页面上总共 6 个。我能够在 Shiny 中有条件地格式化 1 个数据表,但我无法有条件地格式化所有 6 个表。 6 个表中的每一个都有 5 个变量,我想要每个数据表中的第二个变量:如果 >= 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')

【问题讨论】:

  • 请详细说明会出现什么样的问题。您的陈述“我无法有条件地格式化所有 6 个表格”太模糊了。
  • 当我运行此代码时,它适用于 output$1 以有条件地格式化第 2 列,当我尝试将相同的代码添加到 output$2 时,没有任何变化。 output$1 在第 2 列中保持条件格式,但 output$2 没有条件格式。我需要有条件地格式化第 2 列中的所有 6 个数据框。谢谢您的帮助。
  • 首先你不应该将DataTable Id命名为数字,而是:Table1,Table2 ...

标签: r shiny formatting conditional


【解决方案1】:

我已经尝试过您的代码,它对我来说效果很好,请看下面:

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)

每个表都按照您的需要突出显示列。

--> 我刚刚更改了DataTable 的ID,阅读了DT 库并更正了您的括号。

在您的情况下,我会考虑在 formatStyle() 的帮助下格式化整个列而不使用 JS

请下次发reproducible example

[UPDATE] 使用 formatStyle() 的解决方案

您可以在下面看到使用formatStyle() 选项的解决方案,代码的cmets 就在特定行的旁边。

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)

【讨论】:

  • 非常感谢。我宁愿使用 formatStyle(),我只是无法让它工作。任何建议都会非常有帮助。谢谢!
  • 我的代码现在可以工作了,但是,我宁愿使用formatsyle。此外,如果我想创建一个绘图,那么如果我在 6 个数据表中的任何一个中“单击”,就会出现数据绘图。
猜你喜欢
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 2013-08-15
相关资源
最近更新 更多