如何在Shiny App中实现响应式数据框完成ggplot2交互式绘图
问题根因
代码无法实现动态选列绘图的核心原因共两点:
ggplot2的aes()默认使用非标准求值,直接传入input$annee返回的列名字符串,不会被识别为数据框内的对应列- 静态读入的
payerne_temp不需要设置为响应式对象:只有数据本身会随用户操作变动(比如用户上传文件、动态筛选生成数据子集)时才需要做响应式封装,当前固定数据集选列的场景,不需要额外处理数据框的响应式属性
另外原代码selectInput配置存在语法错误,最后一个选项y1981缺失闭合引号,会直接导致代码运行报错。
修正步骤
- 将月份列的因子水平转换逻辑移到全局,数据读入后仅处理一次,避免每次渲染图表重复执行相同操作
- 使用ggplot2官方推荐的
.data代词引用动态列,适配input$annee返回的字符串列名 - 修复选项配置的语法错误
修正后可运行代码
library(shiny) library(readr) library(ggplot2) payerne_temp <- read_csv('payerne_temp.csv') # 提前处理月份因子顺序,全局仅执行一次 payerne_temp$mois <- factor( payerne_temp$mois, levels = c('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre') ) ui <- fluidPage( titlePanel("Evolution des températures"), sidebarLayout( sidebarPanel( selectInput( inputId = "annee", label = "Sélectionnez une année", choices = c( "1972" = "y1972", "1973" = "y1973", "1974" = "y1974", "1975" = "y1975", "1976" = "y1976", "1977" = "y1977", "1978" = "y1978", "1979" = "y1979", "1980" = "y1980", "1981" = "y1981" # 修复原代码缺失的闭合引号 ), selected = "1972", multiple = FALSE ), hr(), helpText("Source: Météosuisse") ), mainPanel( plotOutput("temperaturesPlot") ) ) ) server <- function(input, output) { output$temperaturesPlot <- renderPlot({ ggplot(payerne_temp, aes(x = mois, group = 1)) + # 通过.data代词动态映射用户选中的年份列 geom_line(aes(y = .data[[input$annee]]), color = "blue", linewidth = 1) + geom_line(aes(y = moy_1972_2021), color = "red", linewidth = 1) + labs(y = "Température", x = "Mois") }) } shinyApp(ui, server)
兼容说明
如果你使用的是3.0.0以下的旧版本ggplot2,不支持.data代词,可以替换为兼容写法(该写法目前已被软弃用,优先推荐.data方式),对应折线图层代码改为:
geom_line(aes_string(y = input$annee), color = "blue", linewidth = 1)
后续如果需要新增动态筛选数据行、支持用户上传自定义数据集的功能,再用reactive()封装数据集即可,当前固定数据集场景不需要做响应式处理。
内容的提问来源于stack exchange,提问作者Grizzly Bear
相关产品推荐
相关产品推荐

