【问题标题】:How to format numeric row outputs when using renderTable in R Shiny?在 R Shiny 中使用 renderTable 时如何格式化数字行输出?
【发布时间】:2021-11-15 13:59:38
【问题描述】:

在运行以下 MWE 代码时呈现的 4 行表中,我希望前 2 行中的值以不带小数的形式呈现,而后 2 行中的值以带小数的形式呈现到百分之一和一个 % 符号。如最底部的图像所示,在第一次调用时的默认视图的情况下。这种格式适用于首次调用应用程序和修改它(添加/删除行)时呈现的默认表。

有没有一种有效的方法来做到这一点?如果可能的话,也许不添加函数(将其嵌入到下面的output$table3 <- renderTable(.. 部分中)?

MWE 代码:

library(shiny)
library(shinyMatrix)
library(magrittr)

# Default matrix for initializing
matrix3DefaultRownames <- c("A", "B", "C", "D")
matrix3Default <- data.frame('Series 1' = c(1, 24, 0, 100), row.names = matrix3DefaultRownames) %>% as.matrix()

matrix3Input <- function(inputId, matrix3Default) {
  matrixInput(
    inputId = inputId,
    label = "Input terms:",
    value = matrix3Default,
    rows = list(extend = FALSE, names = TRUE),
    cols = list(extend = TRUE, names = TRUE, editableNames = FALSE, delete = TRUE),
    class = "numeric"
  )
}

ui <- fluidPage(titlePanel("Inputs"), fluidRow(actionButton("modify", "Modify"), tableOutput("table3")))

server <- function(input, output, session) {
  rv <- reactiveValues(
    mat3 = matrix3Input("matrix3", matrix3Default),
    input = matrix3Default,
    colHeader = colnames(input)
  )
  
  observeEvent(input$modify, {
    showModal(modalDialog(rv$mat3))
  })
  
  output$table3 <- renderTable(
    {
      if (isTruthy(input$modify)) {
        req(input$matrix3)
        
        df <- input$matrix3
        rv$mat3 <- matrix3Input("matrix3", df)
        colnames(df) <- paste("Series", 1:ncol(df))
        rownames(df) <- matrix3DefaultRownames
        rv$input <- df
      } else {
        df <- matrix3Default
        colnames(df) <- paste("Series", 1:ncol(df))
        rownames(df) <- matrix3DefaultRownames
      }
      df
    },
    rownames = TRUE,
    colnames = TRUE
  )
}

shinyApp(ui, server)

【问题讨论】:

    标签: r shiny datatables dt


    【解决方案1】:

    @Ronak 的回答很好,但它改变了表格的值。我宁愿使用按列选项render,它允许在不更改值的情况下更改值的显示

    library(DT)
    
    dat <- data.frame(
      x = c(
        1.2,
        24.3,
        0,
        0.999
      ),
      y = c(
        12.8,
        34.7,
        0.1,
        0.05
      )
    )
    
    js <- c(
      "function(data, type, row, meta){",
      "  var rowindex = meta.row;",
      "  if(type === 'display'){",
      "    if(rowindex <= 1){",
      "      return data.toFixed(0);",
      "    }else{",
      "      return (100*data).toFixed(2) + '%';",
      "    }",
      "  }",
      "  return data;",
      "}"
    )
    
    datatable(
      dat,
      options = list(
        columnDefs = list(
          list(targets = c(1, 2), render = JS(js))
        )
      )
    )
    

    【讨论】:

      【解决方案2】:

      您可以使用sprintf 执行此格式化 -

      library(shiny)
      library(shinyMatrix)
      library(magrittr)
      
      # Default matrix for initializing
      matrix3DefaultRownames <- c("A", "B", "C", "D")
      matrix3Default <- data.frame('Series 1' = c(1, 24, 0, 100), row.names = matrix3DefaultRownames) %>% as.matrix()
      
      matrix3Input <- function(inputId, matrix3Default) {
        matrixInput(
          inputId = inputId,
          label = "Input terms:",
          value = matrix3Default,
          rows = list(extend = FALSE, names = TRUE),
          cols = list(extend = TRUE, names = TRUE, editableNames = FALSE, delete = TRUE),
          class = "numeric"
        )
      }
      
      ui <- fluidPage(titlePanel("Inputs"), fluidRow(actionButton("modify", "Modify"), tableOutput("table3")))
      
      server <- function(input, output, session) {
        rv <- reactiveValues(
          mat3 = matrix3Input("matrix3", matrix3Default),
          input = matrix3Default,
          colHeader = colnames(input)
        )
        
        observeEvent(input$modify, {
          showModal(modalDialog(rv$mat3))
        })
        
        output$table3 <- renderTable(
          {
            if (isTruthy(input$modify)) {
              req(input$matrix3)
              
              df <- input$matrix3
              rv$mat3 <- matrix3Input("matrix3", df)
              colnames(df) <- paste("Series", 1:ncol(df))
              rownames(df) <- matrix3DefaultRownames
              rv$input <- df
            } else {
              df <- matrix3Default
              colnames(df) <- paste("Series", 1:ncol(df))
              rownames(df) <- matrix3DefaultRownames
            }
            df[3:4] <- sprintf('%.2f%%', df[3:4])
            #If you don't want to hardcode 3rd and 4th row and select only last2 rows.
            #n <- nrow(df)
            #df[c(n-1, n)] <- sprintf('%.2f%%', df[c(n-1, n)])
            df
          },
          rownames = TRUE,
          colnames = TRUE
        )
      }
      
      shinyApp(ui, server)
      

      【讨论】:

      • 嗨罗纳克。这适用于调用应用程序时的初始表。但是当我向表中添加一列时,该新列在呈现的表中未格式化。
      • 尝试将df[3:4] &lt;- sprintf('%.2f%%', df[3:4])更改为df[3:4, ] &lt;- sprintf('%.2f%%', df[3:4, ])
      • 是的,行得通。鉴于此表的大小始终是有限的(在大多数使用场景中不超过 4-8 行,例如 8 列),我认为这在代码中可以很好且非常清晰地表达出来,
      猜你喜欢
      • 1970-01-01
      • 2019-02-05
      • 2023-03-24
      • 2014-01-07
      • 1970-01-01
      • 2022-01-22
      • 2021-08-04
      • 2021-02-11
      • 1970-01-01
      相关资源
      最近更新 更多