如何在R语言Shiny中重置eventReactive响应式值及解决报错?
Shiny应用重置与响应式值处理问题
我开发了一个使用plotly展示数据的shiny应用,数据通过actionButton加载。在完整应用中,存在大量依赖该加载数据的后续响应式观察者及其他响应式值,最终数据将从文件读取,我希望用户能够重置所有内容,完全回到初始状态。但我发现,除非将响应式值存储在reactiveValues()中,否则无法删除该响应式值或至少将其设为NULL。我更倾向于在观察者中使用req()而非if(!is.null()),并尽可能使用Dat()而非vals$dat的写法。
无法运行的代码
UI代码
library(shiny) library(shinyjs) library(plotly) df <- data.frame(t=seq(as.POSIXct("2024-01-01 00:00:00", tz='UTC'), as.POSIXct("2024-01-02 00:00:00", tz='UTC'), by="1 hour"), V1=sample(1:50,25, replace=T)) ui <-shinyUI(fluidPage( shinyjs::useShinyjs(), fluidRow( actionButton("getdat", "Get my Data"), actionButton("reset", "Reset"), ), fluidRow( plotlyOutput("plot"), )))
Server代码
server<- function(input, output, session) { Dat<-eventReactive(input$getdat, { return(df) }) # 加载数据后禁用按钮 observeEvent(input$getdat,{ shinyjs::disable("getdat") }) output$plot <- renderPlotly({ req(Dat()) Dat() %>% plot_ly() %>% add_trace(x= ~t, y = ~V1, type='scatter', mode='line', visible=TRUE) %>% layout(showlegend=FALSE) }) observeEvent(input$reset,{ Dat()<-NULL shinyjs::enable("getdat") }) } shinyApp(ui,server)
可以正常运行的代码(使用reactiveValues)
server<- function(input, output, session) { vals<-reactiveValues( Dat=NULL ) # 加载数据并禁用按钮 observeEvent(input$getdat,{ vals$Dat<-df shinyjs::disable("getdat") }) output$plot <- renderPlotly({ if(!is.null(vals$Dat)){ vals$Dat %>% plot_ly() %>% add_trace(x= ~t, y = ~V1, type='scatter', mode='line', visible=TRUE) %>% layout(showlegend=FALSE) } }) observeEvent(input$reset,{ vals$Dat<-NULL shinyjs::enable("getdat") }) } shinyApp(ui,server)
补充说明与新问题
我采用了@Stéphane Laurent的解决方案,并加入了完整应用中的部分复杂逻辑。我不清楚如何正确更新响应式容器,也不理解eventReactive与observeEvent的区别。此前我参考相关问题的解答使用了eventReactive。
我知道可以将时间戳更新逻辑加入updateData()函数,并在eventReactive中加入input$t0作为触发事件,但由于处理的数据集非常大,我希望避免每次修改参数都重新计算所有内容。
新增代码(出现报错)
UI代码
ui <-shinyUI(fluidPage( shinyjs::useShinyjs(), fluidRow( actionButton("getdat", "Get my Data"), actionButton("reset", "Reset"), textInput("bin", HTML("Average bin"), value = "1", placeholder = NULL), textInput("t0", HTML("Starttime"), value = '2018/03/28 09:54:27',placeholder = NULL) ), fluidRow( plotlyOutput("plot") )))
工具函数
updateData <- function(dat,bin) { dat<-as.data.frame( dat %>% group_by(t = round_date(t, unit=paste0(bin,' hours')))%>% summarize(V1 = median(V1)) ) return(dat) } updateStarttime <- function(dat,t0){ timediff<-difftime(dat$t[1],as.POSIXct(t0, tz='UTC'), unit='secs') dat$t<-dat$t-seconds(timediff) return(dat) }
Server代码
server<- function(input, output, session) { rawDat <- reactiveVal() timeformat <- reactiveVal() observe( timeformat(grepl('[0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}', input$t0)) ) # 加载数据后禁用按钮 observeEvent(input$getdat,{ rawDat(df) shinyjs::disable("getdat") }) # 对原始数据进行后续转换 Dat <- eventReactive(c(input$getdat,input$bin,input$reset), { req(rawDat()) updateData(rawDat(),input$bin) }) observeEvent(input$t0, { req(Dat(),timeformat()) df<-updateStarttime(Dat(),input$t0) Dat(df) }) output$plot <- renderPlotly({ req(Dat()) Dat() %>% plot_ly() %>% add_trace(x= ~t, y = ~V1, type='scatter', mode='line', visible=TRUE) %>% layout(showlegend=FALSE) }) observeEvent(input$reset,{ rawDat(NULL) shinyjs::enable("getdat") }) } shinyApp(ui,server)
报错信息
Warning: Error in Dat: unused argument (df)
内容的提问来源于stack exchange,提问作者Anke
相关产品推荐
相关产品推荐

