【问题标题】:Add dynamic subtotals to Shiny DataTable将动态小计添加到 Shiny DataTable
【发布时间】:2020-08-08 18:48:33
【问题描述】:

我正在尝试将汇总行添加到显示总计/小计和其他汇总函数的可过滤表中。在下面的示例中,我想要investmentValueProfit 的总数,以及 ROI 的平均值,用于过滤器 AssetSymbol 的任意组合。

这里有图片来展示我想要的结果:

所有资产:

股票选择:

债券选择:

我也在尝试格式化我的列,但是无论我在if 管道中添加此格式化代码的任何位置,它都不起作用。

formatCurrency( ~investment+Value+Profit ) %>%
               formatStyle( c('ROI','Profit'),color = styleInterval(c(0), 
               c('red', 'green')),fontWeight = 'bold') %>%
               formatPercentage(~ROI,digits=1)

R 闪亮代码:

    library(tidyverse)
    library(DT)
    library(formattable)
    library(shiny)
    
    
    
    assetTable <- structure(list(symbol = c("A", "B", "C", "D", "E", "F", "G", 
                                            "H", "I"), Asset = c("Stock", "Stock", "Bond", "Bond", "Stock", 
                                            "Bond", "Stock", "Bond", "Stock"), investment = c(154, 362, 181, 
                                             851, 510, 539, 527, 369, 234), Value = c(330, 763, 911, 535, 
                                             220, 450, 576, 903, 905), Profit = c(176, 401, 730, -316, -290, 
                                             -89, 49, 534, 671), ROI = c(1.14285714285714, 1.10773480662983, 
                                             4.03314917127072, -0.371327849588719, -0.568627450980392, 
                                             -0.165120593692022,0.0929791271347249, 1.44715447154472, 
                                             2.86752136752137)), row.names = c(NA,-9L),
                                             class = c("tbl_df", "tbl", "data.frame"))
    
    
    ui <- fluidPage(
        titlePanel("Table with column summary"),
        
        # Create a new Row in the UI for selectInputs
        fluidRow(
            column(4,
                   selectInput("Asset",
                               "Asset Type:",
                               c("All",
                                 unique(as.character(assetTable$Asset))))
            )
            ,
            column(4,
                   selectInput("symbol",
                               "Symbol",
                               c("All",
                                 unique(as.character(assetTable$symbol))))
            )
        ),
        
        DT::dataTableOutput("table")
    
    )
    
    
    server <- function(input, output) {
        
        # Filter data based on selections
        output$table <- DT::renderDataTable(DT::datatable({
            data <-assetTable 
            
            
            
            if (input$Asset!= "All") {
                data <- data[data$Asset == input$Asset,] 
            }
            
            if (input$symbol != "All") {
                data <- data[data$symbol == input$symbol,]
            }
            data
        }))
        
    }

# Run the application 
shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    为了得到summean,我们可以使用janitor中的adorn_totals

    library(dplyr)
    library(janitor)
    

    另外,因为我们正在重做相同的总结,它可以被做成一个函数

    f1 <- function(dat, colnm, colval) {
      
      dat %>%
        # // filter the rows based on the input string  from colval
        filter({{colnm}} == colval) %>%
        # // create a mean column for ROI
        mutate(ROImean = mean(ROI)) %>%
        # // make use of adorn_totals for the selected columns
        adorn_totals(where = "row", fill = '-', 
                     na.rm = TRUE, name = 'Total', c('investment', 'Value', 
                                                     'Profit', 'ROI', 'ROImean')) %>%
        # // replace the ROI last row (n() => last row index) 
        # // with first element of ROImean
        mutate(ROI = replace(ROI, n(), first(ROImean))) %>%
        # // remove the temporary ROImean column
        select(-ROImean) %>%
        # // change the format of specific columns
        mutate(across(c(investment, Value, Profit), 
               ~ as.character(formattable::currency(., symbol = '$', 
             digits = 2L, format = "f", big.mark = ","))), 
           ROI = as.character(formattable::percent(ROI, digits = 2)))
    }
    

    现在,服务器内的调用变得更加紧凑

    server <- function(input, output) {
      
      # Filter data based on selections
      output$table <- DT::renderDataTable(DT::datatable({
        data <- assetTable 
        
        
        
        if (input$Asset!= "All") {
          data <- f1(data, Asset, input$Asset)
        }
        
        if (input$symbol != "All") {
          data <- f1(data, symbol, input$symbol)
        }
        data
      }))
      
    }
    

    -输出

    【讨论】:

    • 我想在可过滤表中添加一个汇总行,以便所有行仍然可见。我更改了我的问题以包含该要求,很抱歉遗漏了。
    • @tetime 更新了帖子。最后一行只显示Total,但ROI是mean
    • 我可能运行您的代码有误,您能否看看我添加到原始帖子中的图片,它们显示了我希望表格在过滤前后的外观。
    • 我错过了您的代码更新,抱歉浪费您的时间,太好了,谢谢!
    • 完美。我将链接这个答案 我在搜索中遇到了许多类似的未回答问题。谢谢!
    猜你喜欢
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2021-12-23
    • 2013-10-28
    • 2015-02-23
    相关资源
    最近更新 更多