【问题标题】:How to display data tables stored in a list in RShiny App and formating the data tables如何在 R Shiny App 中显示存储在列表中的数据表并格式化数据表
【发布时间】:2021-02-11 16:58:03
【问题描述】:

我想输出几个存储在RShiny 列表中的数据表。该列表始​​终包含不同的数据表,因此RShiny 中的输出必须是动态且呈现的。我在server.R 中调用的函数称为priceInfo <- function(){},并生成一个数据表列表,其中数据表是经过宽格式转换的。

priceInfo() 函数如下所示:(注意:这只是一个示例,该函数有时返回的不仅仅是包含两个数据表的列表)

priceInfo <- function(){
  
  set.seed(123)
  dt.data <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                        'EEX DEB CAL-2021' = rnorm(365, 2, 1), 'PEGAS TTF CAL-2021' = rnorm(365, 2, 1),
                        check.names = FALSE)
  
  foo <- function(DT, colname){
    DT <- DT[, c("date", colname), with = FALSE]
    DT <- DT %>%
      mutate(month = format(date, '%b'), 
             date = format(date, '%d')) %>%
      tidyr::pivot_wider(names_from = date, values_from = colname) %>%
      relocate(`01`, .after = month)
    
    ## Calculate monthly and quarterly mean values: ##
    DT <- setDT(DT)[, monthAvg := rowMeans(.SD, na.rm = TRUE), .SDcols = -1]
    DT <- DT[, quartAvg := mean(monthAvg), ceiling(seq_len(nrow(DT))/3)]
    DT <- DT[, yearAvg := mean(monthAvg), ceiling(seq_len(nrow(DT))/12)]
    
    ## Round all values of the data table to 2 digits: ##
    DT <- DT %>% mutate_if(is.numeric, round, 2)
    
  }
  
  l.testList <- lapply(names(dt.data)[names(dt.data) != "date"], 
                       foo, DT = dt.data)
  setNames(l.testList, names(dt.data)[names(dt.data) != "date"])
  
  
  
}

我尝试了以下方法来显示列表的所有数据表:

服务器:

server <- function(input, output, session){
  tables <- priceInfo()$l.testList
  
  output$maPriceInformationTABLES <- renderUI({
  tableList <- imap(tables, ~ {
    tagList(
      h4(.y), # Note we can sprinkle in other UI elements
      tableOutput(outputId = paste0("table_", .y))
    )
  })
  tagList(tableList)
  })

  # Now render each output
  iwalk(tables, ~{
    output_name <- paste0("table_", .y)
    output[[output_name]] <- renderTable(.x)
  })
}
shinyApp(ui, server)

用户界面:

uiOutput(outputId = "maPriceInformationTABLES")

基本上,表格的输出几乎可以按照我的意愿进行。 但是: 我想使用DT::renderDataTable({}),因为所有表格都相对较宽,并且从未完全显示(缺少 11 列)。

我必须进行哪些更改才能确保所有数据表都正确显示?

我也知道数据表最后应该是什么样子(这里只是单个表的示例):

output$maPriceInformationTABLES<- DT::renderDataTable({

  DT::datatable(dt.tables, rownames = FALSE, escape = FALSE, class = 'cell-border stripe', # 'display cell-border stripe'
                options = list(pageLength = 10, autoWidth = TRUE, scrollX = TRUE,
                               columnDefs = list(list(className = 'dt-center', targets = c(0,1,2,3), width = '200px')),
                               initComplete = JS("function(settings, json) {",
                                                 "$(this.api().table().header()).css({'background-color': '#007d3c', 'color': '#fff'});",
                                                  "}")
                        )
          )
})


编辑:

tableOutput 更改为DTOutput 并将renderTable 更改为renderDT 时,表格如下所示:

同样,表格显示不正确(缺少 11 列)。

我也想要如下的数据表(上面的代码已经是单个数据表了):

而且我不知道如何将此格式应用于所有数据表。

pageLength = 12不起作用,这里是截图:

【问题讨论】:

  • 我不明白这个问题(但我没有仔细阅读您的长文)。您只想要数据表而不是普通表?
  • 我有一个包含多个数据表的列表。然后我会在RShiny中一个接一个地输出这些数据表,考虑到数据表是宽格式的。
  • 你遇到的困难是什么?
  • 问题在我上面的问题中有描述!我已经设法在 RShiny 中输出数据表,但它们没有完全显示(缺少列),并且没有为每个数据表提供名称,只有数字(1、2 等)。见附图
  • 好的,我已经解决了名称的问题,但没有解决显示整个(宽)数据表的问题

标签: r list shiny dt


【解决方案1】:

这就是我认为你所追求的:

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

priceInfo <- function(){
  set.seed(123)
  dt.data <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                        'DEB Cal-2019' = rnorm(365, 2, 1), 'DEB Cal-2021' = rnorm(365, 2, 1),
                        'DEB Cal-2022' = rnorm(365, 2, 1), 'DEB Cal-2023' = rnorm(365, 2, 1),
                        'ATB Cal-2019' = rnorm(365, 2, 1), 'ATB Cal-2021' = rnorm(365, 2, 1),
                        'ATB Cal-2022' = rnorm(365, 2, 1), 'ATB Cal-2023' = rnorm(365, 2, 1),
                        'TTF Cal-2019' = rnorm(365, 2, 1), 'TTF Cal-2021' = rnorm(365, 2, 1),
                        'TTF Cal-2022' = rnorm(365, 2, 1), 'TTF Cal-2023' = rnorm(365, 2, 1),
                        'NCG Cal-2019' = rnorm(365, 2, 1), 'NCG Cal-2021' = rnorm(365, 2, 1),
                        'NCG Cal-2022' = rnorm(365, 2, 1), 'NCG Cal-2023' = rnorm(365, 2, 1),
                        'AUTVTP Cal-2019' = rnorm(365, 2, 1), 'AUTVTP Cal-2021' = rnorm(365, 2, 1),
                        'AUTVTP Cal-2022' = rnorm(365, 2, 1), 'AUTVTP Cal-2023' = rnorm(365, 2, 1),
                        'ATW Cal-2019' = rnorm(365, 2, 1), 'ATW Cal-2021' = rnorm(365, 2, 1),
                        'ATW Cal-2022' = rnorm(365, 2, 1), 'ATW Cal-2023' = rnorm(365, 2, 1),
                        'BRN Cal-2019' = rnorm(365, 2, 1), 'BRN Cal-2021' = rnorm(365, 2, 1),
                        'BRN Cal-2022' = rnorm(365, 2, 1), 'BRN Cal-2023' = rnorm(365, 2, 1),
                        'FEUA MDEC1' = rnorm(365, 2, 1),
                        check.names = FALSE)
  
  foo <- function(DT, colname){
    DT <- DT[, c("date", colname), with = FALSE]
    DT <- DT %>%
      mutate("2020" = format(date, '%b'), 
             date = format(date, '%d')) %>%
      tidyr::pivot_wider(names_from = date, values_from = colname) %>%
      relocate(`01`, .after = "2020")
    
    ## Calculate monthly and quarterly mean values: ##
    DT <- setDT(DT)[, monthAvg := rowMeans(.SD, na.rm = TRUE), .SDcols = -1]
    DT <- DT[, quartAvg := mean(monthAvg), ceiling(seq_len(nrow(DT))/3)]
    DT <- DT[, yearAvg := mean(monthAvg), ceiling(seq_len(nrow(DT))/12)]
    
    ## Round all values of the data table to 2 digits: ##
    DT <- DT %>% mutate_if(is.numeric, round, 2)
    
  }
  
  l.testList <- lapply(names(dt.data)[names(dt.data) != "date"], foo, DT = dt.data)
  l.testList <- setNames(l.testList, names(dt.data)[names(dt.data) != "date"])
  
  return(l.testList)
  
}

ui <- fluidPage(
  uiOutput(outputId = "maPriceInformationTABLES")
)

server <- function(input, output, session){
  tables <- priceInfo()
  
  output$maPriceInformationTABLES <- renderUI({
    tableList <- imap(tables, ~ {
      tagList(
        h4(.y), # Note we can sprinkle in other UI elements
        DTOutput(outputId = paste0("table_", .y))
      )
    })
    tagList(lapply(tableList, br))
  })
  
  # Now render each output
  iwalk(tables, ~{
    output_name <- paste0("table_", .y)
    output[[output_name]] <- renderDT({
      DT::datatable(.x, rownames = FALSE, escape = FALSE, class = 'cell-border stripe', # 'display cell-border stripe'
                    options = list(pageLength = 12, autoWidth = TRUE, scrollX = TRUE,
                                   initComplete = JS("function(settings, json) {",
                                                     "$(this.api().table().header()).css({'background-color': '#007d3c', 'color': '#fff'});",
                                                     "}")
                    )
      )
    })
  })
}
shinyApp(ui, server)

【讨论】:

  • 你为获得滚动条做了什么改变?我在 OP 的代码中看不到问题。我怀疑她使用的是旧版本的 DT。
  • 我无法重现滚动条问题。这是使用DT (0.16) 的最新 CRAN 版本。
  • 感谢您的回答!是否可以仅将第一列的列名从 month 更改为 2020
  • 列宽的定义是您代码的一部分:columnDefs = list(list(className = 'dt-center', targets = c(0,1,2,3), width = '200px')), 只需删除这一行
  • 您总是希望第一列是 2020 年吗?还是取决于年份?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多