【问题标题】:Displaying commas and conditional highlighting in Rshiny - not compatible在 R Shiny 中显示逗号和条件突出显示 - 不兼容
【发布时间】:2018-11-05 17:52:17
【问题描述】:

我有一个 Shiny 应用程序呈现一个数据表,我想在其中合并 2 个条件格式功能

  1. 为大于 1000 的数字添加逗号
  2. 当第 2 列的值 >= 第 1 列中的 1.3x 值时,将蓝色背景应用于第 2 列的值。当第 2 列的值

我问了一个关于如何在SO 帖子中加入逗号的问题。我在下面的脚本中删除了 rowcallback 参数,逗号正确呈现。同样,如果我注释掉 dom 和 formatCurrency 参数,突出显示的条件格式也会正确呈现。

  js_cont_var_lookup <- reactive({
  JS(
      'function(nRow, aData) {
      for (i=2; i < 3; i++) {
      if (parseFloat(aData[i]) > aData[1]*(1.03)) {
        $("td:eq(" + i + ")", nRow).css("background-color", "aqua");
         }
        }
       for (i=2; i < 3; i++) {
       if (parseFloat(aData[i]) < aData[1]*(.7)) {
        $("td:eq(" + i + ")", nRow).css("background-color", "red");
         }
        }
       }'
      ) # close JS
})

shinyApp(
  ui = fluidPage(
    DTOutput("dummy_data_table")
  ),
  server = function(input, output) {
    output$dummy_data_table <- DT::renderDataTable(
      data.frame(A=c(100000, 200000, 300000), B=c(140000, 80000, 310000)) %>%
        datatable(extensions = 'Buttons',
                  options = list(
                    pageLength = 50,
                    scrollX=TRUE,
                    dom = 'T<"clear">lBfrtip',
                    rowCallback = js_cont_var_lookup()
                  )
        ) %>%
        formatCurrency(1:2, currency = "", interval = 3, mark = ",")
    ) # close renderDataTable
  }
)

但是,当我将两者都保留时,数据表会挂起并显示“正在处理”消息。

【问题讨论】:

  • 对您自己的问题不再感兴趣?
  • ismirsehregal,抱歉耽搁了。非常感谢您的工作!

标签: javascript r shiny


【解决方案1】:

这是一个避免rowCallback的解决方案:

library(shiny)
library(DT)
library(data.table)

shinyApp(
  ui = fluidPage(
    DTOutput("dummy_data_table")
  ),

  server = function(input, output) {

    myDisplayData <- data.table(A=c(100000, 200000, 300000), B=c(140000, 80000, 310000))
    myWorkData <- copy(myDisplayData)
    myWorkData[, colors := ifelse(B >= A*1.03, 'rgb(0,255,255)', 'rgb(255, 255, 255)')]
    myWorkData[colors %in% 'rgb(255, 255, 255)', colors := ifelse(B <= A*.7, 'rgb(255, 0, 0)', 'rgb(255, 255, 255)')]

    output$dummy_data_table <- DT::renderDataTable(
      DT::datatable(
        myDisplayData,
        extensions = 'Buttons',
        options = list(
          pageLength = 50,
          scrollX=TRUE,
          dom = 'T<"clear">lBfrtip'
        )
      ) %>% formatStyle('B', target = 'cell', backgroundColor = styleEqual(myDisplayData$B, myWorkData$colors)) %>% 
        formatCurrency(1:2, currency = "", interval = 3, mark = ",")
    ) # close renderDataTable

  }
)
  1. 编辑 --------------

如果您更喜欢使用data.frame

library(shiny)
library(DT)

shinyApp(
  ui = fluidPage(
    DTOutput("dummy_data_table")
  ),

  server = function(input, output) {

    myDisplayData <- data.frame(A=c(100000, 200000, 300000), B=c(140000, 80000, 310000))

    MyColors <- vector(mode = 'character', length = 0L)

    for (i in seq(nrow(myDisplayData))) {
      A <- myDisplayData$A[i]
      B <- myDisplayData$B[i]
      if (B >= A * 1.03) {
        MyColors[i] <- 'rgb(0,255,255)'
      } else if (B <= A * .7) {
        MyColors[i] <- 'rgb(255, 0, 0)'
      }
      else{
        MyColors[i] <- 'rgb(255, 255, 255)'
      }
    }

    output$dummy_data_table <- DT::renderDataTable(
      DT::datatable(
        myDisplayData,
        extensions = 'Buttons',
        options = list(
          pageLength = 50,
          scrollX=TRUE,
          dom = 'T<"clear">lBfrtip'
        )
      ) %>% formatStyle('B', target = 'cell', backgroundColor = styleEqual(myDisplayData$B, MyColors)) %>% 
        formatCurrency(1:2, currency = "", interval = 3, mark = ",")
    ) # close renderDataTable

  }
)
  1. 编辑 --------------

这是一种多列方法,假设所有其他列都指向“A”列:

library(shiny)
library(DT)
library(data.table)

shinyApp(
  ui = fluidPage(
    DTOutput("dummy_data_table")
  ),

  server = function(input, output) {

    myDisplayData <- data.table(replicate(15,sample(round(runif(20,0,300000)), 20, rep=TRUE)))
    names(myDisplayData) <- LETTERS[1:15]
    referenceCol <- "A"
    targetColumns <- names(myDisplayData)[!names(myDisplayData) %in% referenceCol]
    myDisplayData[, index := seq(.N)]

    rowUniqueCols <- paste0("rowUnique", targetColumns)

    for(i in seq(rowUniqueCols)){
      myDisplayData[, (rowUniqueCols[i]) := do.call(paste,c(.SD, sep = "_")), .SDcols=c("index", targetColumns[i])]
    }

    myWorkData <- melt.data.table(myDisplayData, id.vars=c("index", referenceCol), measure.vars = rowUniqueCols)
    myDisplayData[, index := NULL]
    HideCols <- which(names(myDisplayData) %in% rowUniqueCols)
    setnames(myWorkData, "value", "rowUniqueValue")
    myWorkData[, value := as.numeric(sapply(strsplit(rowUniqueValue, "_"), "[[", 2))]
    myWorkData[, variable := NULL]
    myWorkData[, colors := ifelse(value >= .SD*1.3, 'rgb(0,255,255)', 'rgb(255, 255, 255)'), .SDcols=referenceCol]
    myWorkData[colors %in% 'rgb(255, 255, 255)', colors := ifelse(value <= .SD*.7, 'rgb(255, 0, 0)', 'rgb(255, 255, 255)'), .SDcols=referenceCol]

    output$dummy_data_table <- DT::renderDataTable(
      DT::datatable(
        myDisplayData,
        extensions = 'Buttons',
        options = list(
          pageLength = 50,
          scrollX=TRUE,
          dom = 'T<"clear">lBfrtip', 
          columnDefs = list(list(visible=FALSE, targets=HideCols))
        )
      ) %>% formatStyle(columns = targetColumns, valueColumns = rowUniqueCols, target = 'cell', backgroundColor = styleEqual(myWorkData$rowUniqueValue, myWorkData$colors)) %>% 
        formatCurrency(1:15, currency = "", interval = 3, mark = ",")
    ) # close renderDataTable

  }
)

结果:

【讨论】:

  • 这太好了,谢谢。重要的一点 - 我可能有多达 15 列(为简单起见,我在示例中仅包含 2 列)。所以我需要像我的例子一样保留for循环。看起来怎么样?
  • 所有其他列是否仍在引用关于颜色分配的第一列?
  • 顺便说一句:在您的问题中,您提到的是 1.3x,但在您的 JS 函数中它是 1.03。我现在在我的代码中将其设为 1.3。
  • 刚刚更新了我的 2. 编辑。现在颜色指的是行唯一的帮助列。它现在可以正常工作了 - 请检查。
  • 只需将我的示例更改为:referenceCol &lt;- names(myDisplayData)[3]targetColumns &lt;- names(myDisplayData)[4:length(names(myDisplayData))]
猜你喜欢
  • 1970-01-01
  • 2019-04-28
  • 2023-01-25
  • 2019-09-20
  • 2014-04-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 2019-03-06
相关资源
最近更新 更多