使用响应式数据框时如何格式化数据表值?

Posted

技术标签:

【中文标题】使用响应式数据框时如何格式化数据表值?【英文标题】:How to format data table values when using a reactive data frame? 【发布时间】:2022-01-20 23:04:16 【问题描述】:

在下面的 MWE 代码中,我以前使用基本 Shiny renderTable() 并使用以下简单的代码行成功格式化数据表输出:format1 <- function(x)format(x, nsmall = 2, big.mark=",")

但是由于下面的 MWE 被部署在一个操作更大数据帧的应用程序中,我切换到 DT 包来渲染数据表,因为它有明显的好处。

但是,我在 DT 之前使用的用于格式化表格输出的旧代码不适用于 DT!所以,使用 DT 包,我如何格式化指定列(在这种情况下为 ColA 和 ColB)的数字输出,所以它们显示 2 个小数,每 3 个 0 用“,”分隔,并且可能能够显示货币比如指定列开头的€?我不希望所有列都以相同的方式自动格式化,因为完整 App 的数据表比这个 MWE 中的更复杂,并且某些列需要不同的格式。

我研究了 DT 格式化解决方案,但我似乎碰壁了,因为我的数据框是反应式的。

MWE 代码:

library(dplyr)
library(DT)
library(shiny)
library(tidyverse)

ui <-
  fluidPage(
    h3("Data table:"),
    tableOutput("data"),
    h3("Sum the data table columns:"),
    radioButtons(
      inputId = "grouping",
      label = NULL,
      choiceNames = c("By period 1", "By period 2"),
      choiceValues = c("Period_1", "Period_2"),
      selected = "Period_1",
      inline = TRUE
    ),
    DT::dataTableOutput("sums")
  )

server <- function(input, output, session) 
  data <- reactive(
    data.frame(
      Period_1 = c("2020-01", "2020-02", "2020-03", "2020-01", "2020-02", "2020-03"),
      Period_2 = c(1, 2, 3, 3, 1, 2),
      ColA = c(1000.01, 20, 30, 40, 50, 60),
      ColB = c(15.06, 25, 35, 45, 55, 65)
    )
  )
  
  summed_data <- reactive(
    data() %>%
      group_by(!!sym(input$grouping)) %>%
      select("ColA","ColB") %>%
      summarise(across(everything(), sum))
    )
  
  output$data <- renderTable(data())
  
  output$sums <- renderDT(summed_data(),rownames = FALSE)
  


shinyApp(ui, server)

【问题讨论】:

【参考方案1】:

DT 包提供了几个格式化程序 functions 来格式化表格列,例如在你的情况下formatCurrency 似乎合适:

library(dplyr)
library(DT)
library(shiny)
library(tidyverse)

ui <-
  fluidPage(
    h3("Data table:"),
    tableOutput("data"),
    h3("Sum the data table columns:"),
    radioButtons(
      inputId = "grouping",
      label = NULL,
      choiceNames = c("By period 1", "By period 2"),
      choiceValues = c("Period_1", "Period_2"),
      selected = "Period_1",
      inline = TRUE
    ),
    DT::dataTableOutput("sums")
  )

server <- function(input, output, session) 
  data <- reactive(
    data.frame(
      Period_1 = c("2020-01", "2020-02", "2020-03", "2020-01", "2020-02", "2020-03"),
      Period_2 = c(1, 2, 3, 3, 1, 2),
      ColA = c(1000.01, 20, 30, 40, 50, 60),
      ColB = c(15.06, 25, 35, 45, 55, 65)
    )
  )
  
  summed_data <- reactive(
    data() %>%
      group_by(!!sym(input$grouping)) %>%
      select("ColA","ColB") %>%
      summarise(across(everything(), sum))
  )
  output$data <- renderTable(data())
  
  output$sums <- renderDT(
    summed_data() %>% 
      datatable(rownames = FALSE) %>% 
      formatCurrency(c("ColA", "ColB"), currency = '\U20AC', digits = 2)
  )
  


shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:3057
#> Adding missing grouping variables: `Period_1`

【讨论】:

以上是关于使用响应式数据框时如何格式化数据表值?的主要内容,如果未能解决你的问题,请参考以下文章

vue3修改响应式代理值

合并数据框时如何避免重复值?

如何使用正则表达式规则从 json 数据响应中检索值?

如何格式化 XML 响应 - Python

如何设计 API 接口,实现统一格式返回?

如何使用JSON格式 POST数据到服务器