簡體   English   中英

使用動態過濾器聚合 R Shiny 中的數據

[英]Using dynamic filters to aggregate data in R Shiny

我有這種格式的數據:

Category Subcategory   User   Count1    Count2
  A           a        New     3000      2000
  A           a        Old      300       200
  A           b        New     4000      3000
  A           b        Old      400       300
  B           c        New     4000      3000
  B           c        Old      600       400

我以這種方式為類別、子類別和用戶以及 output 數據表編寫了 3 個過濾器:

    selectInput('cat', 'Category', choices = c('All', category)),
    selectInput('sub', 'Subcategory', choices = c('All', subcategory)),
    selectInput('user', 'User', c('All', 'New', 'Old')),
    DT::dataTableOutput('table')

選擇參數中的categorysubcategory是列表。 我可以通過用戶輸入以這種方式過濾數據:

output$table <- DT::renderDataTable({
    if(input$cat == 'All'){data <- data}
    else{data <- data[data$Category == input$cat, ]}
    if(input$user == 'All'){data <- data}
    else{data <- data[data$User== input$user, ]}
    if(input$sub == 'All'){data <- data}
    else{data<- data[data$Subcategory == input$sub, ]}
})

我遇到的問題是,當用戶輸入“全部”參數時,我需要聚合計數列。 例如,如果用戶為子類別和用戶輸入“全部”,為類別輸入“A”,則 output 數據表應如下所示:

Category Subcategory   User   Count1    Count2
  A           All      All     7700      5500

或者

Category  Count1    Count2
  A        7700      5500

我可以為此編寫 if-else 條件,但在實際數據中有 6-8 個過濾器,我想知道是否有更簡單的方法來聚合數據,而無需為所有聚合組合編寫 if-else 控件(如聚合上的New所有類別和子類別上的用戶聚合所有類別、子類別和用戶等)。

你可以在DT::renderDataTable中嘗試這樣的事情:

output$table <- DT::renderDataTable({
idx <- which(c(input$cat, input$user, input$sub) != "All")
myvars <- colnames(data)[1:3][idx]

data %>%
  {`if`(input$cat ==  "All", . , filter(., Category == input$cat))} %>% 
  {`if`(input$user == "All", . , filter(., User == input$user))} %>%
  {`if`(input$sub ==  "All", . , filter(., Subcategory == input$sub))} %>%
  {`if`(length(myvars) == 0, ., group_by_at(., myvars) %>% 
          summarise_at(vars(matches("^Count")), sum))}
})

簡短說明:

summarisedplyraggregate物。 summarise_atsummarise的一個特例:在第一個參數中,您描述了要聚合(或匯總)的所有變量。 我輸入了matches("^Count") ,這意味着所有以"Count"開頭的變量都應該被匯總。 第二個參數是聚合 function sum

我添加了“”作為過濾器的默認值......

    selectInput('cat', 'Category', choices = c('','All', category)),
    selectInput('sub', 'Subcategory', choices = c('','All', subcategory)),
    selectInput('user', 'User', c('','All', 'New', 'Old')),
    DT::dataTableOutput('table')

...並根據 UI 輸入更改列值。

output$table <- DT::renderDataTable({
 if(input$cat == '' | input$sub == '' | input$user == ''){return(NULL)}
 else{
    if(input$cat == 'All'){data$Category <- 'All'}
    else{data <- data[data$Category == input$cat, ]}
    if(input$user == 'All'){data$User <- 'All'}
    else{data <- data[data$User== input$user, ]}
    if(input$sub == 'All'){data$Subcategory <- 'All'}
    else{data<- data[data$Subcategory == input$sub, ]}
     }
 aggregate.data = aggregate(.~Category+Subcategory+User, data, sum)
})

以這種方式,如果用戶和子類別輸入為“全部”且類別列為“A”,則首先過濾包含“A”和“全部”和“全部”的所有行的數據,然后將結果數據集聚合到這些三列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM