R Shiny renderPlotly多条件筛选绘图报错修复方案咨询
报错根因
- 核心语法错误:直接将
if/else判断语句接在%>%管道符后方。管道符的运行规则是把左侧的输出结果作为右侧函数的第一个传入参数,因此原写法等价于if(完整数据集, input$y == "tmean"),而if()仅接受长度为1的逻辑值作为判断条件,传入多行多列的数据集自然会触发「条件长度大于1,仅使用第一个元素」「参数无法解析为逻辑值」的报错。 - 逻辑设计缺陷:逐一枚举三个温度值写
if/else判断的写法冗余,且原代码将Y轴变量放入group_by分组维度,会导致聚合粒度过细,无法生成正确的时序折线。
修复要点
- 不要把条件判断直接接在管道后,先单独完成数据筛选步骤再执行后续管道操作
- 去掉冗余的
if/else枚举判断:由于需要筛选的variable列取值和Y轴选择的input$y值完全对应,直接判断选中的Y值是否在variable列的取值范围内做对应筛选即可,同时兼容非温度类的Y轴变量场景 - 修正分组聚合逻辑:仅按X轴变量、用户选择的分组(color)变量分组,计算Y轴变量的均值即可,不需要把Y轴变量加入分组
- 聚合计算时增加
na.rm = TRUE参数避免空值导致计算失败,增加.groups = "drop"取消分组残留,避免后续操作出现警告
修复后可直接运行的代码
library(shiny) library(tidyverse) library(plotly) options(shiny.maxRequestSize=1024*1024^2) ui = navbarPage("Data", tabPanel("Uploading Files", sidebarLayout( sidebarPanel( radioButtons( "File_Type", label = "选择文件类型", choices = list(".csv/txt" = 1, ".xlsx" = 2), selected = 1, inline = TRUE ), fileInput('file2', '上传数据文件', accept = c( 'text/csv', 'text/comma-separated-values,text/plain', '.csv', '.xlsx' ))), mainPanel( verbatimTextOutput("summary") ) )), tabPanel("数据绘图", sidebarLayout(sidebarPanel( selectInput("x", label = "选择X轴变量:", choices = NULL), selectInput("y", label = "选择Y轴变量: ", choices = NULL), selectInput("color", label = "选择分组变量(可选): ", choices = NULL)), mainPanel( plotlyOutput("TSM") ))) ) server = function(input, output, session) { myData = reactive({ req(input$file2) inFile = input$file2 if (is.null(inFile)) return(NULL) data = read.csv(inFile$datapath, header = TRUE) data }) observe({ data = req(myData()) updateSelectInput(session, 'x', choices = names(data), selected = names(data)[which(names(data)=="year")]) updateSelectInput(session, 'y', choices = names(data), selected = names(data)[which(names(data)=="tmean")]) updateSelectInput(session, 'color', choices = names(data), selected = names(data)[which(names(data)=="month")]) }) output$summary = renderPrint({ summary(myData()) }) df2 = reactive({ req(myData(),input$x, input$y, input$color) plot_data <- myData() # 匹配variable列取值自动筛选对应数据子集 if("variable" %in% names(plot_data) && input$y %in% unique(plot_data$variable)){ plot_data <- plot_data %>% filter(variable == input$y) } # 分组聚合计算均值 plot_data %>% group_by(.data[[input$x]], .data[[input$color]]) %>% dplyr::summarise(AvgTemp = mean(.data[[input$y]], na.rm = TRUE), .groups = "drop") }) output$TSM = renderPlotly({ req(df2(), input$x, input$y, input$color) p <- df2() %>% ggplot(aes(x = .data[[input$x]], y = AvgTemp, color = as.factor(.data[[input$color]]))) + labs(color = "图例") + geom_line() + ggtitle("分月时序图") ggplotly(p) }) } shinyApp(ui = ui, server = server)
验证说明
使用提供的样例数据测试时,选择X轴为year/month、Y轴为tmean/TMax/TMin、分组变量为month/year,即可自动筛选对应温度类型的子集,正常渲染可交互的plotly时序图,不会再触发原有的条件判断报错。
内容的提问来源于stack exchange,提问作者Ed_Gravy
相关产品推荐
相关产品推荐

