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

使用golem构建Shiny应用遇ggplot传参错误求助

问题:使用golem开发Shiny应用时ggplot报错无法打包

背景

我使用golem包开发Shiny应用,功能为让用户通过选择框选取数据集vars中的X、Y变量并生成绘图。数据集的定义与清洗在data-raw/vars.R中完成,代码如下:

## code to prepare `vars` dataset goes here

rm(list=ls())
Sys.setenv(LANG = "en")
cat("\014")
# install.packages("data.table")
# install.packages("ggplot2")
# install.packages("shiny")
# install.packages("dplyr")

library(data.table)
library(shiny)
library(ggplot2)
library(dplyr)

#import data
HRS <- fread("C:/myShinyApp/shinyapptest/inst/extdata/HRS_small.csv")
#create a new data only including CESD, age, sex and edyrs
col_need = c("CESD", "age", "sex","edyrs")
vars <- HRS[, ..col_need]
vars_names = colnames(vars)
vars = as.data.frame(vars)

#clean data
clean_inputdat <- function(d_in){
  n = NCOL(d_in)
  col_names = colnames(d_in)
  for (i in 1:n){
    d = d_in[,i]
    if ( is.numeric(d) ) {
      d_in = d_in [!is.na(d),]
    }else if( is.character(d) ){
      d_in = d_in [!startsWith(d, "."),]
      d_in = d_in [!is.na(d),]
      d_in[, i] = as.numeric(d_in[,i])
      colnames(d_in)[i] = col_names[i]
    }
  }
  return (d_in)
}
vars = clean_inputdat(vars)
# try to solve the problem: xlim need finite values
vars = na.omit(vars)
table(is.na(vars))

usethis::use_data(vars, overwrite = TRUE)
usethis::use_data(vars_names, overwrite = TRUE)

app_server.R中的代码如下:

#' The application server-side

#' @param input,output,session Internal parameters for {shiny}.
#'     DO NOT REMOVE.
#' @import shiny
#' @import ggplot2
#' @import data.table
#' @rawNamespace import(dplyr, except=c(first, between, last))
#' @importFrom stats lm
#' @noRd

globalVariables(c("vars_names"))
globalVariables(c("vars"))

# Your application server logic
app_server <- function(input,output){
  output$ycol = renderUI({
    selectInput(inputId = "ycol", label = "Y Variable", vars_names)
  })
  output$xcol = renderUI({
    data_available = vars_names[! vars_names %in% input$ycol]
    selectInput(inputId = "xcol", label = "X Variable", data_available)
  })

  X <- eventReactive(input$go, {
    vars[, c(input$xcol)]
  })

  Y <- eventReactive(input$go, {
    vars[, c(input$ycol)]
  })

output$plot1 <- renderPlot({
  input$go
  ggplot2::ggplot(vars, ggplot2::aes(X(), Y())) + ggplot2::geom_point() + 
  ggplot2::geom_smooth(method = lm) 
 })
}

错误详情

报错出现在以下代码行:
ggplot2::ggplot(vars, ggplot2::aes(X(), Y())) + ggplot2::geom_point() + ggplot2::geom_smooth(method = lm)

错误信息:

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

特殊情况:单独运行run_dev.R会触发该错误,但依次运行app_ui.R、app_server.R、run_app.R后再运行run_dev.R,应用可正常生成绘图。该问题导致无法成功打包应用。

解决方案

问题根源

X()和Y()是eventReactive返回的反应式对象,在ggplot的aes()中直接调用时,ggplot会将其视为函数而非实际数据;同时单独运行run_dev.R时,反应式环境未正确初始化,进一步加剧了这个问题。

修改代码

调整app_server.R中的绘图逻辑,移除不必要的eventReactive对象,改用动态列名引用的方式:

# 移除原来的X和Y两个eventReactive定义,替换绘图部分代码
output$plot1 <- renderPlot({
  # 确保所有必要输入都已存在
  req(input$xcol, input$ycol, input$go)
  ggplot2::ggplot(vars, ggplot2::aes(x = .data[[input$xcol]], y = .data[[input$ycol]])) + 
    ggplot2::geom_point() + 
    ggplot2::geom_smooth(method = stats::lm) 
})

额外检查

  1. 确认data-raw/vars.R运行后,data目录下生成了vars.rda和vars_names.rda文件,打包时这些数据会被正确包含。
  2. 确保globalVariables的声明正确,避免R CMD CHECK的NOTE。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:48:26