#r #shiny #user-input #shinydashboard #shiny-server
Вопрос:
У меня есть 4 PickerInputs в приложении R Shiny, и на выходе получается отфильтрованный кадр данных из этих входных данных. Иногда эти входные данные выбираются, а иногда нет (значит, не применяется никакой фильтр).
Проблема: я хочу, чтобы все эти входные данные были каскадированы путем выбора друг друга.
column(width=2, id="filters",
shinyWidgets::pickerInput(
inputId = "filter_a",
label = 'Filter A',
choices = c(""),
multiple = FALSE),
shinyWidgets::pickerInput(
inputId = "filter_b",
label = 'Filter B',
choices = c(""),
multiple = FALSE),
shinyWidgets::pickerInput(
inputId = "filter_c",
label = 'Filter C',
choices = c(""),
multiple = FALSE),
shinyWidgets::pickerInput(
inputId = "filter_d",
label = 'Filter D',
choices = c(""),
multiple = FALSE)
)
Сервер:
Способ написания этих взаимозависимых каскадных фильтров «если бы иначе» выглядит не очень хорошо. Это определенно не оптимизированный код. Как я могу написать его как функцию?
Мне нужно, чтобы каждый фильтр наблюдал за остальными 3 фильтрами и обновлял варианты.
Пример обновления «фильтра C»:
observeEvent(c(input$filter_a, input$filter_b, input$filter_d),
{updatePickerInput(session = session,
inputId = 'filter_c',
choices = if(input$filter_a==" All" amp; input$filter_b == " All" amp; input$filter_d == " All"){sort(c(" All", unique(df$column_c)))
}else if(input$filter_a ==" All" amp; input$filter_b == " All" amp; input$filter_d != " All"){sort(c(" All", unique(df$column_c[df$column_d==input$filter_d])))
}else if(input$filter_a ==" All" amp; input$filter_b != " All" amp; input$filter_d == " All"){sort(c(" All", unique(df$column_c[df$column_b==input$filter_b])))
}else if(input$filter_a !=" All" amp; input$filter_b == " All" amp; input$filter_d == " All"){sort(c(" All", unique(df$column_c[df$column_a==input$filter_a])))
}else if(input$filter_a ==" All" amp; input$filter_b != " All" amp; input$filter_d != " All"){sort(c(" All", unique(df$column_c[df$column_b==input$filter_b amp; df$column_d==input$filter_d])))
}else if(input$filter_a !=" All" amp; input$filter_b == " All" amp; input$filter_d != " All"){sort(c(" All", unique(df$column_c[df$column_a==input$filter_a amp; df$column_d==input$filter_d])))
}else if(input$filter_a !=" All" amp; input$filter_b != " All" amp; input$filter_d == " All"){sort(c(" All", unique(df$column_c[df$column_a==input$filter_a amp; df$column_b==input$filter_b])))
}else{sort(c(" All", unique(df$column_c[df$column_a==input$filter_a amp; df$column_b==input$filter_b amp; df$column_d==input$filter_d])))},
selected = c(" All"))
})
column_a, column_b, column_c и column_d-это 4 столбца фильтра в моем df, на основе которых я выбираю filter_a, filter_b, filter_c, filter_d соответственно.
Комментарии:
1. вам следует подумать об использовании
uiOutput()
и.renderUI()
2. используйте
case_when()
вместо столькихifelse
Ответ №1:
Возможно, это было бы немного лучше
observeEvent(c(input$filter_a, input$filter_b, input$filter_d), {
if(input$filter_a==" All") {fa <- unique(df$column_a)} else fa <- input$filter_a
if(input$filter_b==" All") {fb <- unique(df$column_b)} else fb <- input$filter_b
if(input$filter_d==" All") {fd <- unique(df$column_d)} else fd <- input$filter_d
choices <- c(" All", unique(df$column_c[df$column_a %in% fa amp; df$column_b %in% fb amp; df$column_d %in% fd]))
updatePickerInput(session = session, inputId = 'filter_c', choices = choices, selected = c(" All"))
})