首页 > 解决方案 > 使用 R 中的 tryCatch 从处理函数中的 gamlss 模型预测数据

问题描述

我在tryCatch()创建的函数中使用 R 中的函数时遇到问题。

我想做的是:

  1. 根据模型结果模拟数据
  2. gamlss使用我的模型分析模拟数据
  3. 使用该predict函数在新的值范围内提取模型预测
  4. 将这些预测存储在数据框中
  5. 多次这样做

我的主要问题是我的模型有些不稳定,有时预测有点疯狂,当我尝试用gamlss. 我的目标是在我的模拟函数中编写一个tryCatch语句,并且基本上只是在发生错误时再次运行模拟/预测代码。(我知道这不是最优的,我也可以使用repeat例如递归语句将其编写并运行它,直到我没有收到错误但我得到的错误很少,以至于连续获得两个的概率很低,而且我对这项任务有足够的麻烦。)

所以我尽可能地简化了我的代码,并创建了一个模型仍然有效的虚拟数据框。

我写在我认为错误所在的代码中(使用没有找到mod_sim对象的预测函数)。很可能在那里,因为cat这条线正上方的打印,而正下方的不打印。

我认为有一些关于如何tryCatch工作的事情我不太了解,我很难理解哪些对象保存在函数的哪些部分以及何时可以调用它们......

这是我到目前为止的代码。错误发生在 l.84(在脚本中标识)。数据和代码可以在这里找到。

library(tidyverse)
library(gamlss)
library(gamlss.dist)

#Load data
load('DHT.RData')



#Run original model
mod_pred<-gamlss(harvest_total ~ ct,
                          data = DHT,
                          family = DPO)



#Function to compute predictions based on model
compute_CI_trad_gamlss<-function(n.sims=200, mod){#,
 
  #DF for simulations
  df_sims<-as.data.frame(DHT)
  
  #Dateframe with new data to predict over
  new.data.ct<<-expand.grid(ct=seq(from=5, to=32, length.out=50))
  
  
  #matrix to store predictions
  preds.sim.trad.ct <<- matrix(NA, nrow=nrow(new.data.ct), ncol=n.sims)
  
  
  
  #Number of obs to simulate
  n<-nrow(df_sims)
  
  
  
  
  #Simulation loop (simulate, analyze, predict, write result)
  for(i in 1:n.sims){
    
    
   #Put in tryCatch to deal with potential error on first run 
  tryCatch({
    
    #Create matrix to store results of simulation
    y<-matrix(NA,n,1)
    
    
    #in DF for simulations, create empty row to be filled by simulated data
    df_sims$sim_harvest<-NA
    
    
    #Loop to simulate observations
    for(t in 1:n){
      
      
      #Simulate data based on model parameters
      y[t]<-rDPO(n=1, mu=mod$mu.fv[t], sigma = mod$sigma.fv[t])
      
    }#enf of simulation loop

    
    #Here I want the result of the simulation loop to be pasted in the df_sims dataset
    df_sims$sim_harvest<-y
    
    #Analysis of simulated data
    mod_sim<-gamlss(sim_harvest ~ ct,
                        data = df_sims,
                        family = DPO)
    
    
    
    
    #Refit the model if convergence not attained  
    if(mod_sim$converged==T){
      #If converged do nothing
    } else {
    #If not converged refit model
    mod_sim<-refit(mod_sim)
    }
    
    
    cat('we make it to here!\n')
    #Store results in object
    ct <<-as.vector(predict(mod_sim,   newdata = new.data.ct,   type='response'))
    
    cat('but not to here :( \n')
    
    #If we made it down here, register err as '0' to be used in the if statement in the 'finally' code
    err<<-0
    
    
    
    }, 
    
    #If error register the error and write it!
    error = function(e) {
    
      #If error occured, show it
       cat('error at',i,'\n')
       
      #Register err as 1 to be used in the if statement in the finally code below
      err<<-1
      
      
      
    }, 
    
    
    
    finally = {

      if(err==0){
        #if no error, do nothing and keep going outside of tryCatch


        }#End if err==0
      else if (err==1){
        #If error, re-simulate data and do the analysis again
        
        y<-matrix(NA,n,1)
        df_sims$sim_harvest<-NA
        
        
        #Loop to simulate observations
        for(t in 1:n){
          #Simuler les données basées sur les résultats du modèle
          y[t]<-rDPO(n=1, mu=mod$mu.fv[t], sigma = mod$sigma.fv[t])
          
        }#enf of simulation loop
        
        
        #Here I want the result of the simulation loop to be pasted in the df_sims dataset
        df_sims$sim_harvest<-y
        
        #Analysis of simulated data
        mod_sim<-gamlss(sim_harvest ~ ct,
                        data = df_sims,
                        family = DPO)
        
        
        cat('we also make it here \n')
        #Store results in object
        ct <<-as.vector(predict(mod_sim,   newdata = new.data.ct,   type='response'))
        cat('but not here... \n')
        
        
       }#End if err==1, 
    }#End finally 
    
    
    
    )#End tryCatch
    
    
    #Write predictions for this iteration to the DF and start over
    preds.sim.trad.ct[,i] <<-ct
    
    
    
    #Show iteration number
    cat(i,'\n')
  }
  
  

#Do some more stuff here 


#Return results
  return(preds = list(ct= list(predictions=preds.sim.trad.ct)))
}



#Run simulation and store object
result<-compute_CI_trad_gamlss(n.sims=20, mod=mod_pred)

无论如何,我希望有人可以提供帮助!

非常感谢!

标签: rloopssimulationpredictgamlss

解决方案


因此,经过一番反复试验,我设法使其工作。我相信问题出在mod_sim没有保存到全局环境中的对象上。predict(或predict.gamlss此处)可能没有在对象的功能环境中寻找,mod_sim尽管我不明白为什么它不会。无论如何<<- ,对函数中创建的每个对象使用(即从函数中分配全局环境中的对象)似乎都可以解决问题。如果有人对为什么会发生这种情况有解释,尽管我很高兴理解我做错了什么!


推荐阅读