Shiny中无需reactive定义dplyr临时对象的方法问询
问题解答
1. 不用reactive()创建依赖input的dplyr对象是否可行?
不行。Shiny的server函数在应用启动时仅执行一次,直接赋值的对象只会基于启动时的input$var初始值生成一次。之后用户切换下拉选项时,这个对象不会自动重新计算更新——因为没有触发响应式更新的机制,无法感知input的变化。
比如你给出的示例代码里,data在server启动时就固定了,用户切换input$var后图表不会变化,就是因为data没有重新生成。
2. 用reactive()包裹后能否像普通dplyr对象一样操作?
完全可以,但要记住reactive对象是一个函数,调用时需要加括号才能获取实际的数据对象。
修正后的示例代码
library(shiny) library(tidyverse) ui <- fluidPage( shiny::selectInput("var", label = "Input", choices = names(diamonds)), shiny::plotOutput("plot"), # 新增下游分析的统计表格输出 shiny::tableOutput("stats") ) server <- function(input, output, session) { # 用reactive包裹处理后的dplyr对象 processed_data <- reactive({ diamonds %>% # 这里可以添加任意dplyr操作,比如筛选、变换列等 select(price, !!sym(input$var)) }) # 基于reactive数据绘图,调用时需加括号 output$plot <- renderPlot({ processed_data() %>% ggplot(aes(y = price, x = .data[[input$var]])) + geom_point() }) # 下游分析:用reactive数据做统计,调用同样加括号 output$stats <- renderTable({ processed_data() %>% group_by(.data[[input$var]]) %>% summarise(avg_price = mean(price), count = n()) %>% arrange(desc(avg_price)) }) } shinyApp(ui, server)
关键说明
processed_data()每次调用时,会自动检查依赖的input$var是否变化,若变化则重新执行dplyr操作生成新数据。- 你可以像操作普通data.frame一样,对
processed_data()执行任何dplyr函数(filter()、group_by()、summarise()等),只要记得调用时加上括号。
内容的提问来源于stack exchange,提问作者alejandro_hagan
相关产品推荐
相关产品推荐

