R语言 相互依赖的闪亮文本输入

whitzsjs  于 2023-01-10  发布在  其他
关注(0)|答案(2)|浏览(169)

我正在shiny上开发一个关于生物多样性的应用程序。这个应用程序有两个文本输入(vernacularNamescientificName用于生物)和一个选择输入,可以使用一年。我正在努力;
1.链接2个文本输入,以便如果用户键入本地名称,则在科学名称文本输入中填充相应的科学名称。
1.同样,如果用户键入学名,本地名框将自动更新为相应的本地名。
1.如果用户开始键入一个科学或方言名称,则会出现一个所有相似名称的列表,用户可以从中选择。
看看我的代码,我到目前为止。
此处提供数据,请下载https://raw.githubusercontent.com/Karuitha/shiny_karuitha/master/final_data.csv

################################################################################
## Download and load packages manager pacman ----
if(!require(pacman)) {
    install.packages("pacman")
    library(pacman)
}

################################################################################
# Download and load required packages ----
pacman::p_load(
    shiny, glue, plotly, leaflet, 
    shinythemes, tidyverse
)

###############################################################################
if(!require(shiny.react)){
    remotes::install_github("Appsilon/shiny.react")}

if(!require(shiny.fluent)){
    remotes::install_github("Appsilon/shiny.fluent")}

################################################################################
## Load the pre-processed data ----
final_data <- read_csv("final_data.csv",
                       
                       col_types = 'ccddccdd')

################################################################################
## Create the UI ----
ui <- fluidPage(
    
    ## Header panel
    headerPanel(HTML("<h1 style='color: grey'>Prevalence of Selected Species in Poland and Germany</h1>")),
    
    ## Add a themes selector for the app
    shinythemes::themeSelector(),
    
    ## Side bar layout
    sidebarLayout(
        
        sidebarPanel(
            
            HTML("<h3>User Input</h3>"),
            
            ## User enters vernacular name 
            HTML("<h4>Enter Vernacular Name</h4>"),
            ## Create a drop down inputs selection
            textInput(inputId = "vernacularname", 
                      label = "Choose a Vernacular Name",
                      value = "Box bug",
                      #placeholder = "Norway Maple",
                      width = "100%"
            ),
            
            ## User has the choice to enter scientific name
            HTML("<h4>Enter Scientific Name</h4>"),
            ## Create a drop down inputs selection
            textInput(inputId = "scientificname", 
                      label = "Choose a Scientific Name",
                      value = "Acer platanoides",
                      #placeholder = "Norway Maple",
                      width = "100%"
                      
            ),
            
            ## User has the choice to enter scientific name
            HTML("<h4>Enter Year </h4>"),
            
            ## Create a slider input for the years
            selectInput(inputId = "year", 
                        label = "Choose year",
                        choices = sort(unique(final_data$year)),
                        selected = 2020,
                        multiple = FALSE)
            
        ),
        
        ## Main panel will contain the leaflet output
        mainPanel(
            
            
            leafletOutput("mymap"), width = "100%", height = "100%"
        )
        
    )
    
)

################################################################################
## Create the server with leaflet output ----
server <- function(input, output, session){
    
    
    ## Create a reactive for the current data ----
    this_data <- reactive({
        
        final_data %>% 
            
            filter(vernacularName == input$vernacularname,
                   
                   year == input$year)
    })
    
    
    ## Render an leaflet map
    output$mymap <- renderLeaflet(
        
        leaflet(
            
            this_data()
            
            
        ) %>%
            addProviderTiles('OpenStreetMap.HOT') %>%
            ## 
            ## Stamen.Toner
            addCircleMarkers(
                color = "red", 
                radius = ~ individualCount^0.3,
                stroke = TRUE,
                fillOpacity = 0.8,
                popup = ~paste(
                    
                    "<strong> Country: </strong>", country, "<br>",
                    "<strong> Locality: </strong>", locality, "<br>",
                    "<strong> Count: </strong>", individualCount, "<br>"
                )
                
                
            )
        
    )
    
    
    
}

################################################################################
## Run the application ----
shinyApp(ui, server)
################################################################################
toe95027

toe950271#

这个应用程序完成了你想要的三件事。然而,首先你必须过滤掉重复的行;这样,只有scientificNamesvernacularNames的唯一组合出现在数据中。这样,只有一个scientificName与所选的vernacularName相关联,反之亦然。

library(shiny)
library(shinyWidgets)
library(tidyverse)

data <- read.csv("https://raw.githubusercontent.com/Karuitha/shiny_karuitha/master/final_data.csv")

data <- data %>% group_by(vernacularName, scientificName) %>% distinct() %>% ungroup()

ui <- fluidPage(
  
  pickerInput("text1", "Vernacular Name", choices = sort(unique(data$vernacularName)), options = list(`live-search` = TRUE)),
  pickerInput("text2", "Scientific Name", choices = sort(unique(data$scientificName)), options = list(`live-search` = TRUE))
  
)

server <- function(input, output, session) {
  
  observeEvent(input$text1, {
    
    updatePickerInput(session = session, inputId = "text2",
                      choices = sort(unique(data$scientificName)), options = list(`live-search` = TRUE),
                      selected = unique(data$scientificName[data$vernacularName == input$text1]))
}, ignoreInit = TRUE)
  observeEvent(input$text2, {
    
    updatePickerInput(session = session, inputId = "text1",
                      choices = sort(unique(data$vernacularName)), options = list(`live-search` = TRUE),
                      selected = unique(data$vernacularName[data$scientificName == input$text2]))
    
  }, ignoreInit = TRUE)
}

shinyApp(ui, server)
5n0oy7gb

5n0oy7gb2#

让两个textInput字段相互依赖的风险在于,您可能会陷入自我更新的循环,一种解决方法是跟踪最后一个值,并注意 * 哪个 * 值正在更改。
下面是一个使用本地数据的简单例子来说明这一点。使用这种方法,对一个条目总是有两个React,但第二个总是空操作:例如,如果我们更新Word,则它改变Synonym,这重新触发观察事件;然而,在第二个观察中,与存储的变化(在lasts$...中)没有什么不同,因此它很快逃逸。

library(shiny)

words <- data.frame(
  word = c("apple", "pear"),
  synonym = c("fuji", "bosc")
)

shinyApp(
  ui = fluidPage(
    textInput("word", "Word"),
    textInput("synonym", "Synonym")
  ),
  server = function(input, output, session) {
    lasts <- reactiveValues(word = "", synonym = "")
    observeEvent({
      input$word
      input$synonym
    }, {
      if (!identical(lasts$synonym, input$synonym)) {
        # synonym changed
        validate(
          need(input$synonym %in% words$synonym,
               paste("Synonym needs to be one of:",
                     paste(sQuote(words$synonym, FALSE), collapse = ", ")))
        )
        newword <- words$word[match(input$synonym, words$synonym)]
        updateTextInput(session, "word", value = newword)
        lasts$word <- newword
        lasts$synonym <- input$synonym
      } else if (!identical(lasts$word, input$word)) {
        validate(
          need(input$word %in% words$word,
               paste("Word needs to be one of:",
                     paste(sQuote(words$word, FALSE), collapse = ", ")))
        )
        newsyn <- words$synonym[match(input$word, words$word)]
        updateTextInput(session, "synonym", value = newsyn)
        lasts$word <- input$word
        lasts$synonym <- newsyn
      }
    }) %>% throttle(1000)
    onSessionEnded(function() stopApp())
  }
)

相关问题