如何使变量通过反应来聚合数据框列?

How to make the variable to aggregate data frame columns by reactive?

在下面的 MWE 代码中,如下图所示,aggregate() 函数用于对数据框中的列求和。我希望用户能够通过单击单选按钮选择要聚合的变量,Period_1Period_2。目前以下仅针对 Period_1.

编码

如何修改每个 aggregate() 函数中的 $Period... 以反映用户单选按钮输入?所以本例中用户也可以按周期2进行汇总。

MWE 代码:

library(shiny)

data <- 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(10,20,30,40,50,60),
                   ColB=c(15,25,35,45,55,65)
                   )

ui <- 
  fluidPage( 
    
    h3("Data table:"),
    tableOutput("data"),
    h3("Sum the data table columns:"),
    radioButtons(
      inputId = 'vetaDataView2',
      label = NULL,
      choices = c('By period 1','By period 2'),
      selected = 'By period 1',
      inline = TRUE
    ),
    tableOutput("totals")  
  ) 
  

server <- function(input, output, session) {
  
  sumColA   <- aggregate(data$ColA~Period_1,data,sum)
  sumColB   <- aggregate(data$ColB~Period_1,data,sum)
  
  totals <- as.data.frame(c(sumColA, sumColB[2]))
  
  colnames(totals) <- c("Period_1","Sum Col A","Sum Col B")
  
  output$data <- renderTable(data)
  output$totals <- renderTable(totals)

}

shinyApp(ui, server)

实现您想要的结果的一个选项是使用 pasteas.formula 创建公式以根据用户输入聚合您的数据库:

注意:为了让我的生活更轻松一些,我切换到 choiceNameschoiceValues

library(shiny)

data <- 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(10, 20, 30, 40, 50, 60),
  ColB = c(15, 25, 35, 45, 55, 65)
)

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


server <- function(input, output, session) {
  sumColA <- reactive({
    fmlaA <- as.formula(paste("ColA", input$vetaDataView2, sep = " ~ "))
    aggregate(fmlaA, data, sum)
  })

  sumColB <- reactive({
    fmlaB <- as.formula(paste("ColB", input$vetaDataView2, sep = " ~ "))
    aggregate(fmlaB, data, sum)
  })

  output$data <- renderTable(data)
  output$totals <- renderTable({
    totals <- as.data.frame(c(sumColA(), sumColB()[2]))

    colnames(totals) <- c(input$vetaDataView2, "Sum Col A", "Sum Col B")

    totals
  })
}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:6231