#r #shiny #shiny-server #shinyapps #shiny-reactivity
Вопрос:
Ниже приведен сценарий, который я создал для блестящего приложения, которое я создал. Я пытаюсь создать своего рода целевую страницу (я даже не знаю, правильная ли это фраза), которая позволяет вам выбирать, какой набор данных вы используете. Вы заметите, что в начале сценария есть df
и df2
(они оба являются одним и тем же набором данных, но это не имеет значения).
Что я хотел бы сделать, так это, возможно, создать начальную «страницу», которая даст вам возможность выбрать, с каким набором данных вы работаете. Как только это будет выбрано, вам потребуется выполнить настройку, которую вы видите ниже, но с одним примечательным исключением: если df2
выбрано, оно не будет включать опцию выбора:
sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80))
Но вы сможете выбирать из всех других входных данных.
Я даже не знаю, с чего начать, так как же лучше всего этого добиться?
library(dbplyr) library(dplyr) library(shiny) library(shinyWidgets) library(DT) df lt;- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') df2 lt;- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') ui lt;- fluidPage( titlePanel("Sample"), sidebarLayout( sidebarPanel( radioButtons("mydata", label = "Choose dataframe", choices = c("df","df2"), inline=TRUE), selectizeInput("data1", "Select State", choices = c(unique(df$state))), selectizeInput("data2", "Select County", choices = NULL), selectizeInput("data3", "Select City", multiple = TRUE, choices = NULL), selectizeInput("data4", "Select Demo", choices = c("All", unique(df$demo))), selectizeInput("data5", "Select Status", choices = c("All", unique(df$status))), sliderInput("age", label = h3("Select Age Range"), 18, 35, value = c(18, 20), round = TRUE, step = 1), sliderInput("score1", label = h3("Select Score1 Range"), min = 0, max = 100, value = c(20,80)), conditionalPanel(condition = "input.mydata=='df'", sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80)) ), prettyCheckboxGroup("phones", h3("Only Include Valid Phone Numbers?"), selected = "Yes", choices = list("Yes")), downloadButton("download", "Download Data") ), mainPanel( DTOutput("table") ) ) ) server lt;- function(input, output, session){ mydf lt;- reactive({get(input$mydata)}) observeEvent(input$data1, { df lt;- mydf() #if (input$data1 != "All") { updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county[df$state == input$data1]))) # } else { # updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county))) # } }, priority = 2) observeEvent(c(input$data1, input$data2), { df lt;- mydf() if (input$data2 != "All") { updateSelectizeInput(session, "data3", "Select City", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$county == input$data2]))) } else { #if (input$data1 != "All") { updateSelectizeInput(session, "data3", "Select City", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$state == input$data1]))) # } else { # updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city))) # } } }, priority = 1) filtered_data lt;- reactive({ temp_data lt;- mydf() if (input$data1 != "All") { temp_data lt;- temp_data[temp_data$state == input$data1, ] } if (input$data2 != "All") { temp_data lt;- temp_data[temp_data$county == input$data2, ] } if (input$data3 != "All") { temp_data lt;- temp_data[temp_data$city %in% input$data3, ] } if (input$data4 != "All") { temp_data lt;- temp_data[temp_data$demo == input$data4, ] } if (input$data5 != "All") { temp_data lt;- temp_data[temp_data$status == input$data5, ] } df2 lt;- temp_data %gt;% dplyr::filter(age gt;= input$age[1] amp; age lt;= input$age[2] amp; score1 gt;= input$score1[1] amp; score1 lt;= input$score1[2]) if (input$mydata=="df") df2 lt;- df2 %gt;% dplyr::filter(score2 gt;= input$score2[1] amp; score2 lt;= input$score2[2]) df3 lt;- if (is.null(input$phones)) df2 else df2 %gt;% dplyr::filter(!is.na(phone)) df3 %gt;% dplyr::select(unique_id, first_name, last_name, phone) }) output$table lt;- renderDT( filtered_data() ) output$download lt;- downloadHandler( filename = function() { paste("universe", "_", date(), ".csv", sep="") }, content = function(file) { write.csv(filtered_data() %gt;% distinct_all(), file, row.names = FALSE) } ) } shinyApp(ui, server)
Ответ №1:
Попробуй это
library(dbplyr) library(dplyr) library(shiny) library(shinyWidgets) library(DT) df lt;- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') df2 lt;- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') df2$unique_id lt;- df2$unique_id*2 ## just to check if switching works ui lt;- fluidPage( titlePanel("Sample"), sidebarLayout( sidebarPanel( radioButtons("mydata", label = "Choose dataframe", choices = c("df","df2"), inline=TRUE), selectizeInput("data1", "Select State", choices = c(unique(df$state))), selectizeInput("data2", "Select County", choices = NULL), selectizeInput("data3", "Select City", choices = NULL, multiple = TRUE), selectizeInput("data4", "Select Demo", choices = c("All", unique(df$demo))), selectizeInput("data5", "Select Status", choices = c("All", unique(df$status))), sliderInput("age", label = h3("Select Age Range"), 18, 35, value = c(18, 20), round = TRUE, step = 1), sliderInput("score1", label = h3("Select Score1 Range"), min = 0, max = 100, value = c(20,80)), conditionalPanel(condition = "input.mydata=='df'", sliderInput("score2", label = h3("Select Score2 Range"), min = 0, max = 100, value = c(20,80)) ), prettyCheckboxGroup("phones", h3("Only Include Valid Phone Numbers?"), selected = "Yes", choices = list("Yes")), downloadButton("download", "Download Data") ), mainPanel( DTOutput("table") ) ) ) server lt;- function(input, output, session){ mydf lt;- reactive({get(input$mydata)}) observeEvent(input$data1, { df lt;- mydf() #if (input$data1 != "All") { updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county[df$state == input$data1]))) # } else { # updateSelectizeInput(session, "data2", "Select County", server = TRUE, choices = c("All", unique(df$county))) # } }, priority = 2) observeEvent(c(input$data1, input$data2), { req(mydf()) df lt;- mydf() if (input$data2 != "All") { updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city[df$county == input$data2]))) } else { #if (input$data1 != "All") { updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city[df$state == input$data1]))) # } else { # updateSelectizeInput(session, "data3", "Select City", server = TRUE, choices = c("All", unique(df$city))) # } } }, priority = 1) filtered_data lt;- reactive({ req(input$data3) temp_data lt;- mydf() if (input$data1 != "All") { temp_data lt;- temp_data[temp_data$state == input$data1, ] } if (input$data2 != "All") { temp_data lt;- temp_data[temp_data$county == input$data2, ] } if (input$data3 != "All") { temp_data lt;- temp_data[temp_data$city %in% input$data3, ] } if (input$data4 != "All") { temp_data lt;- temp_data[temp_data$demo %in% input$data4, ] } if (input$data5 != "All") { temp_data lt;- temp_data[temp_data$status %in% input$data5, ] } df2 lt;- temp_data %gt;% dplyr::filter(age gt;= input$age[1] amp; age lt;= input$age[2] amp; score1 gt;= input$score1[1] amp; score1 lt;= input$score1[2]) if (input$mydata=="df") df2 lt;- df2 %gt;% dplyr::filter(score2 gt;= input$score2[1] amp; score2 lt;= input$score2[2]) df3 lt;- if (is.null(input$phones)) df2 else df2 %gt;% dplyr::filter(!is.na(phone)) df3 %gt;% dplyr::select(unique_id, first_name, last_name, phone) }) output$table lt;- renderDT( filtered_data() ) output$download lt;- downloadHandler( filename = function() { paste("universe", "_", date(), ".csv", sep="") }, content = function(file) { write.csv(filtered_data() %gt;% distinct_all(), file, row.names = FALSE) } ) } shinyApp(ui, server)
Комментарии:
1. Спасибо, хотя одно уточнение: как насчет удаления
score2
ввода, когдаdf2
он выбран?2. Спасибо! Ты крут!
3. Кое-что, что я заметил: скажем, я выбираю из
df
своегоstate
набора в AZ иage
между 18-20 и обоимиscore1
иscore2
устанавливаю между 20-80. Это точно отражено в приложении, показывающем 14 записей. НО , допустим, я переключусь сdf
наdf2
, он останется на этом номере. На самом деле это должно показывать 37 строк. Похоже, что когда я переключаюсь между DFs, хотя он успешно удаляет возможность использованияscore2
, он все еще включает диапазон 20-80 в фильтр. Когда на самом деле он вообще не должен быть отключенscore2
на основе фильтрации, когда я переключаюсь наdf2
. Не могли бы вы знать, как это исправить?4. О, а также фильтруется только путем включения действительных телефонных номеров для достижения желаемого номера записи. Забыл включить это в свой ответ выше из-за ограничений персонажа. Имеет ли это смысл? Еще раз спасибо за всю вашу помощь!
5. Это тоже влияет
observeEvent(input$data1, {...})
. Пожалуйста, примите ответ, если на ваш первоначальный вопрос был дан ответ.