You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R Shiny运行ggplot报错:传入函数作为全局data参数求解

问题背景
  • 数据来源:NBA 2022赛季球员场均数据统计页面
  • 数据预处理流程:从页面「Share & Export」菜单选择「Get table as CSV (for Excel)」选项,全选生成的表格文本复制到Excel中,使用「Text to columns」功能按逗号分隔符拆分数据,之后将文件保存为.csv后缀格式
  • 开发目标:搭建Shiny交互应用,配置出场分钟数、出场场次滑块控件,以及球队筛选复选框,实现带悬浮弹窗提示的plotly交互图表
  • 运行报错信息:

Warning: Error in ggplot: You're passing a function as global data. Have you misspelled the data argument in ggplot()

原始代码
library(shiny)
library(ggplot2)
library(dplyr)
library(plotly)
library(tidyverse)

Player_Stats<-read.csv("2021-2022 Indiv Per Game Stats.csv")
colnames(Player_Stats)[11]<-"FG%"
colnames(Player_Stats)[14]<-"ThreeP%"
colnames(Player_Stats)[17]<-"TwoP%"
colnames(Player_Stats)[18]<-"eFG%"
colnames(Player_Stats)[21]<-"FT%"     
ui<-fluidPage(
      titlePanel("Player Stats"),
      sidebarLayout(
        sidebarPanel(
          sliderInput("input1",
                      "Minutes",
                      min=0,
                      max = 48,
                      value = 0),
          sliderInput("Input2",
                      "Games Played",
                      min = 0,
                      max = 82,
                      value = 0),
          checkboxGroupInput(inputId = "tm_input",
                             label = "Team",
                             choices = unique(Player_Stats$Tm),
                             selected = unique(Player_Stats$Tm))
        ),
        mainPanel(
          plotOutput("plot1"),
          plotOutput("plot2"),
          dataTableOutput("Player_StatsTable")
        )
      )
    )
    
    server<-function(input, output){
      output$plot1<-renderPlotly({
        x<-Player_Stats %>% ggplot(aes(x=PTS, y=`ThreeP%`,color=Tm,
                                                text=paste("Player:",Player, "PPG:",PTS, "3P%:", `ThreeP%`*100, "Team:",Tm)))+
            geom_point()+
            xlab("Points per Game")+
            ylab("Three Point %")+
            ggtitle("PPG and 3P% by Player")+
            theme(plot.title = element_text(hjust = 0.5))
        ggplotly(x)
      })
      output$plot2<-renderPlotly({
        y<-Player_Stats %>% ggplot(aes(x=PTS, y=`TwoP%`,color=Tm,
                                             text=paste("Player:",Player, "PPG:",PTS, "2P%:", `TwoP%`*100, "Team:",Tm)))+
            geom_point()+
            xlab("Points per Game")+
            ylab("Two Point %")+
            ggtitle("PPG and 2P% by Player")+
            theme(plot.title = element_text(hjust = 0.5))
        ggplotly(y)
      })
      Player_Stats=reactive({
        Player_Stats %>% 
          dplyr::filter(Tm %in% input$Tm_,.preserve = TRUE) %>%
          dplyr::filter(MP>=input$input1) %>% 
          dplyr::filter(G>=input$input2)
      })
      output$Player_StatsTable<-renderDataTable({
        Player_Stats
      })
    }
    shinyApp(ui=ui,server=server)
问题排查结果

共6处导致报错/功能异常的问题:

  1. 变量名冲突:全局环境读入的原始数据框命名为Player_Stats,后续server内又定义了同名的响应式对象,导致ggplot调用数据时拿到的是响应式函数本身而非数据框,直接触发题目中的核心报错
  2. 输出组件不匹配:UI端使用plotOutput承接静态ggplot输出,但server端用renderPlotly渲染交互图表,类型不匹配会导致图表无法正常加载
  3. 输入ID拼写错误:两处ID拼写不匹配:一是球队筛选复选框定义的inputId为tm_input,响应式数据过滤时错写为input$Tm_;二是出场场次滑块定义的inputId为Input2(首字母大写I),过滤逻辑错写为input$input2(首字母小写i),均无法正确读取用户选择的筛选值
  4. 响应式数据未生效:两处绘图逻辑完全没有使用过滤后的响应数据,滑块、复选框的筛选操作不会对图表生效
  5. 响应式对象调用方式错误:Shiny中响应式对象本质是函数,调用时必须加括号,否则读取到的是函数定义而非计算结果
  6. 表格渲染逻辑错误:renderDataTable内直接传入了响应式对象本身,未加括号执行,会导致表格无法正常渲染
修复后可运行代码
library(shiny)
library(ggplot2)
library(dplyr)
library(plotly)
library(tidyverse)

# 重命名原始数据,避免和后续响应式对象重名
raw_player_stats<-read.csv("2021-2022 Indiv Per Game Stats.csv")
colnames(raw_player_stats)[11]<-"FG%"
colnames(raw_player_stats)[14]<-"ThreeP%"
colnames(raw_player_stats)[17]<-"TwoP%"
colnames(raw_player_stats)[18]<-"eFG%"
colnames(raw_player_stats)[21]<-"FT%"     

ui<-fluidPage(
      titlePanel("Player Stats"),
      sidebarLayout(
        sidebarPanel(
          sliderInput("input1",
                      "Minutes",
                      min=0,
                      max = 48,
                      value = 0),
          sliderInput("Input2",
                      "Games Played",
                      min = 0,
                      max = 82,
                      value = 0),
          checkboxGroupInput(inputId = "tm_input",
                             label = "Team",
                             choices = unique(raw_player_stats$Tm),
                             selected = unique(raw_player_stats$Tm))
        ),
        mainPanel(
          # 替换为plotly专属输出组件
          plotlyOutput("plot1"),
          plotlyOutput("plot2"),
          dataTableOutput("Player_StatsTable")
        )
      )
    )
    
    server<-function(input, output){
      # 修正响应式数据命名、输入ID拼写
      filtered_stats <- reactive({
        raw_player_stats %>% 
          dplyr::filter(Tm %in% input$tm_input,.preserve = TRUE) %>%
          dplyr::filter(MP>=input$input1) %>% 
          dplyr::filter(G>=input$Input2)
      })

      output$plot1<-renderPlotly({
        # 调用过滤后的响应数据必须加括号,新增百分比保留1位小数优化展示
        x<-filtered_stats() %>% ggplot(aes(x=PTS, y=`ThreeP%`,color=Tm,
                                                text=paste("Player:",Player, "PPG:",PTS, "3P%:", round(`ThreeP%`*100,1), "Team:",Tm)))+
            geom_point()+
            xlab("Points per Game")+
            ylab("Three Point %")+
            ggtitle("PPG and 3P% by Player")+
            theme(plot.title = element_text(hjust = 0.5))
        # 明确指定悬浮提示读取text映射内容
        ggplotly(x, tooltip = "text")
      })
      output$plot2<-renderPlotly({
        y<-filtered_stats() %>% ggplot(aes(x=PTS, y=`TwoP%`,color=Tm,
                                             text=paste("Player:",Player, "PPG:",PTS, "2P%:", round(`TwoP%`*100,1), "Team:",Tm)))+
            geom_point()+
            xlab("Points per Game")+
            ylab("Two Point %")+
            ggtitle("PPG and 2P% by Player")+
            theme(plot.title = element_text(hjust = 0.5))
        ggplotly(y, tooltip = "text")
      })
      
      output$Player_StatsTable<-renderDataTable({
        filtered_stats()
      })
    }
    shinyApp(ui=ui,server=server)

内容的提问来源于stack exchange,提问作者Tamir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:15:30