[英]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')
選擇參數中的category
和subcategory
是列表。 我可以通過用戶輸入以這種方式過濾數據:
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))}
})
簡短說明:
summarise
是dplyr
的aggregate
物。 summarise_at
是summarise
的一個特例:在第一個參數中,您描述了要聚合(或匯總)的所有變量。 我輸入了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.