【问题标题】:How to update data between multiple observeEvents with shiny如何使用闪亮更新多个观察事件之间的数据
【发布时间】:2021-11-23 12:10:47
【问题描述】:

如何在另一个observeEvent中重用observeEvent处理的数据?

#ui.r
library(shiny)
library(ggplot2)
library(shinyWidgets)
library(DT)

dataset <- diamonds
shinyUI(fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      
      actionButton("read", "read_diamonds"),
      
      pickerInput('filter1',
                  'clarity_Filter1',
                  choices=c(""),
                  multiple  =  TRUE,
                  options = list(actionsBox=TRUE,liveSearch=TRUE),
                  ),
      
      sliderInput('filter2','table_Filter2', min=0, max=100, value=c(0, 100))
      
      ),
    mainPanel(
      dataTableOutput("display"),
    ),

    )
  )
  )
#server.r
library(shiny)
library(DT)

function(input, output, session) {
  
  #Initial setting
  observeEvent(input$file, {
    
    diamond_df <- diamonds

    #filter1 update
    clarity_choise <- as.vector(unique(diamond_df$clarity))
    updatePickerInput(
      session = session,
      inputId = "clarity_Filter1",
      choices = clarity_choise,
      selected = clarity_choise,
      options = list(
        actionsBox  =  TRUE,
        liveSearch = TRUE
      ),
    )
    
    #filter2 update
    max_value <- max(as.numeric((diamond_df$table)))
    min_value <- min(as.numeric((diamond_df$table)))
    updateSliderInput(
      session = session,
      inputId = "nega_char_slier",
      max = max_value ,
      min = min_value ,
      value = c(min,max)
    )
        
    #display
    output$display = renderDataTable(diamond_df,options= list(lengthMenu = c(5, 10, 20), pageLength = 5))
    
    
  })
  
  #What to do if filter1,2 is updated
  observeEvent(c(input$filter1,
                 input$filter2),{
    
    #data update
    diamond_df <- diamond_df %>% filter(clarity %in% input$filter1)
    diamond_df <- diamond_df %>% filter(input$filter2[1]<table & input$filter2[2]>table)
    
    #display
    output$display = renderDataTable(diamond_df,options= list(lengthMenu = c(5, 10, 20), pageLength = 5))
    
    })
  }

你想用示例代码做什么

  1. 按“阅读”以阅读钻石并更新净度和表。显示数据表。

  2. 对1中读入的数据更新filter1和filter2,数据也随之更新,显示数据表。

但是因为1的范围和2的范围不同,所以没有数据,出现错误。

警告:过滤器错误:找不到对象'diamond_df'

遇到这种情况我该怎么办?

【问题讨论】:

  • 您应该使用reactiveValues 对象在observeEvents 之间传递数据。另外,input$file 是什么?它没有在 ui 中定义。
  • 另外,output$display 应该只定义一次,一旦你有一个reactiveValues 对象,它就可以在观察者之外定义。
  • 感谢您的评论。我第一次听到反应式价值观。你如何使用它? input$file 是 input$read 中的错误。

标签: r shiny


【解决方案1】:

也许您可以使用如下所示的 reactiveValues 对象。

library(shiny)
library(ggplot2)
library(shinyWidgets)
library(DT)

dataset <- diamonds
ui <- shinyUI(fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      
      actionButton("read", "read_diamonds"),
      
      pickerInput('filter1',
                  'clarity_Filter1',
                  choices=c(""),
                  multiple  =  TRUE,
                  options = list(actionsBox=TRUE,liveSearch=TRUE),
      ),
      
      sliderInput('filter2','table_Filter2', min=0, max=100, value=c(10, 100))
      
    ),
    mainPanel(
      DTOutput("display")
    )
    
  )
)
)

#server.r

server <- function(input, output, session) {
  
  diamond <- reactiveValues( df=NULL )
  
  ###Initial setting
  observe({diamond$df <- diamonds})
  
  observeEvent(input$read, {
  
    
    df1 <- diamonds
    
    #filter1 update
    clarity_choise <- as.vector(unique(df1$clarity))
    
    updatePickerInput(
      session = session,
      inputId = "filter1",
      choices = clarity_choise,
      selected = clarity_choise,
      options = list(
        actionsBox  =  TRUE,
        liveSearch = TRUE
      ),
    )

    #filter2 update
    max_value <- max(as.numeric(df1$table))
    min_value <- min(as.numeric(df1$table))
    updateSliderInput(
      session = session,
      inputId = "filter2",
      max = max_value ,
      min = min_value ,
      value = c(min_value,max_value)
    )
    
  })
  
  #display
  output$display = renderDT(datatable(diamond$df),options= list(lengthMenu = c(5, 10, 20), pageLength = 5))
  
  #What to do if filter1,2 is updated
  observeEvent(c(input$filter1,
                 input$filter2),{
                   
                   #data update
                   if (is.null(input$filter1)) {
                     diamond$df <- diamonds %>% 
                            dplyr::filter( input$filter2[1]<table & input$filter2[2]>table)
                   }else{
                     diamond$df <- diamonds %>% dplyr::filter(clarity %in% input$filter1) %>% 
                       dplyr::filter( input$filter2[1]<table & input$filter2[2]>table)
                   } 
                   
                 }, ignoreInit = TRUE)
  
}

shinyApp(ui = ui, server = server)

【讨论】:

  • 感谢您编写代码。让我问您两个问题。 1:observe ({diamond$df &lt;-diamonds})这是在做什么? 2:是observeEvent (input $ read)的一部分,但分配给df1df1&lt;-diamonds。我不应该使用diamond$df 吗?比如clarity_choise &lt;-as.vector (unique (df1$clarity)) 而不是clarity_choise &lt;-as.vector (unique (diamond $ df $ clarity))
  • 1.在实际用例中,您可以将反应对象分配给diamond$df。 2. 好问题。如果您执行df1 &lt;- diamond$df,那么一旦您进行了子集化,您将无法返回原始数据,除非您有一个重置按钮可以重新分配为diamond$df &lt;- diamonds。试试看。
  • 我明白了。非常感谢。如果可能的话,我会问另一个相关的问题。如果你能负担得起,如果你能看到它,我会很高兴。 stackoverflow.com/questions/70080821/…
猜你喜欢
  • 1970-01-01
  • 2018-05-26
  • 2021-02-20
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 2019-06-11
相关资源
最近更新 更多