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

R Shiny报错‘mydata未找到’,控制台运行正常求排查方案

解决Shiny中gamlss::getTGD()找不到数据的问题

问题描述

  • R Shiny应用在控制台直接运行正常,但清空R环境后执行RunApp()时,抛出mydata not found错误
  • 已尝试在ui()/server()函数外、server()内部定义mydata,但gamlss包的getTGD()函数仍无法识别该数据对象
  • 错误核心:getTGD()依赖拟合gamlss模型对象gmod时使用的原始数据集,但该数据集无法被函数正确定位

用户提供的核心server()代码片段:

server <- function(input, output, session) {

 output$plot_irt <- renderPlot(
    width=600,
    height =400,
    {

  if(input$Education_dich==0){educ=0}else{educ=1}
  
  mydata=read.csv('data/mydata.csv',header=T, sep = '\t')
  
  gmod=gamlss(IADL_IRT_transf ~ cs(Age, by = as.factor(Education_dich)) + 
                as.factor(Education_dich), family = BE, data = mydata, trace = FALSE)
  
  newdata=setNames(data.frame(matrix(ncol = 6, nrow = 1)), c('RecordID','Age','Education_dich','Sex','IADL_IRT','IADL_IRT_transf'))
  newdata$Age <- input$Age
  newdata$Education_dich <- educ
  newdata$IADL_IRT <- input$IADL_IRT
  newdata$IADL_IRT_transf <- input$IADL_IRT/100
  
  NORM <- getTGD(gmod, newdata=newdata)$resid 

  # 后续绘图逻辑...
  })

问题根源

gamlss()默认不会将完整数据集嵌入模型对象,仅保存数据集的名称。当getTGD()调用时,会尝试在全局环境中查找该名称的数据集:

  • 控制台运行时,全局环境存在该数据集,因此正常
  • 清空环境后启动Shiny,renderPlot()运行在独立的本地环境中,getTGD()无法在全局环境找到数据集,即使本地环境已定义mydata也无效

解决方案

方案1:拟合模型时嵌入数据集(推荐)

在gamlss()中添加save.data = TRUE参数,强制将数据集嵌入模型对象,这样getTGD()可直接从模型内部获取数据,无需依赖外部环境:

gmod=gamlss(IADL_IRT_transf ~ cs(Age, by = as.factor(Education_dich)) + 
              as.factor(Education_dich), family = BE, data = mydata, 
            trace = FALSE, save.data = TRUE)

方案2:指定getTGD()的执行环境

显式告诉getTGD()在当前本地环境中查找数据集,添加envir参数:

NORM <- getTGD(gmod, newdata=newdata, envir = environment())$resid

environment()指向当前renderPlot()的本地环境,确保函数能找到定义好的mydata。

方案3:全局提前加载数据集(不推荐)

在shinyApp()调用前全局加载数据集,让getTGD()能在全局环境找到它:

# 在shinyApp()之前定义
mydata <- read.csv('data/mydata.csv',header=T, sep = '\t')

shinyApp(ui = ui, server = server)

此方法会让数据集长期占用内存,不符合Shiny模块化设计原则,仅作为临时替代方案。

复现代码验证

针对用户提供的iris示例,修改后可解决报错:

library(shiny)
library(ggplot2)
library(gamlss)

data("iris")
iris=subset(iris, Species !='setosa')
iris$Species =ifelse(iris$Species=='versicolor',1,0)
plot <- ggplot(data = iris, aes(x = Sepal.Length)) + geom_histogram()


ui <- fluidPage(
    
    titlePanel('Mytitle'),
    
    navbarPage("Choose a tab:",
               tabPanel("Tab1",
                        sidebarLayout(
                            sidebarPanel(numericInput("Petal.Length", "Petal Length", min = 1, max = 7, value = 4, step=0.01),
                                         numericInput("Petal.Width", "Petal Width", min = 0.1, max = 2.5, value = 1.3, step=0.01),
                                         selectInput("Species", "Species",choices=c('species1'=1,'species2' =2) )),
                            mainPanel( plotOutput("myplot", width = 150, height = 100))
                            )),

               tabPanel("Tab2",
                            mainPanel(  fluidRow( column(width=12,
                                       hr() ))))
    )
) 


server <- function(input, output, session) {
  
    output$myplot <- renderPlot(
        width=600,
        height =400,
        {
        
            if(input$Species==0){spec=0}else{spec=1}

            # 添加save.data=True嵌入数据集
            gmod=gamlss(Sepal.Length ~ Sepal.Width + Species, family = NO, data = iris, trace = FALSE, save.data = TRUE)
            
            NORM <- tryCatch(
              getTGD(gmod, newdata=iris[1,])$resid,
              error = function(err) {
                cat('Error with getTGD().', err$message, "\n") })

            plot + ggtitle(paste0(NORM))

       } )}


shinyApp(ui = ui, server = server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:44:58