使用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) })
额外检查
- 确认
data-raw/vars.R运行后,data目录下生成了vars.rda和vars_names.rda文件,打包时这些数据会被正确包含。 - 确保
globalVariables的声明正确,避免R CMD CHECK的NOTE。
内容的提问来源于stack exchange,提问作者Ann
相关产品推荐
相关产品推荐

