Создание пользовательского интерфейса/сервера на основе первоначального выбора

#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, {...}) . Пожалуйста, примите ответ, если на ваш первоначальный вопрос был дан ответ.