使用 R 中的 tryCatch 从处理函数中的 gamlss 模型预测数据

Predicting data from gamlss model in handler function using tryCatch in R

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

我想做的是:

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

我的主要问题是我的模型有点不稳定,有时预测有点乱,当我尝试用 gamlss 分析它时会产生错误。我的 objective 是在我的模拟函数中写一个 tryCatch 语句,并且在发生错误的情况下基本上简单地 运行 第二次 simulation/prediction 代码。 (我知道这不是最优的,我也可以使用 repeat 和 运行 将其写在递归语句中,直到我没有得到错误但我得到的错误足够少的概率连续获得两个是很低的,我已经受够了这个任务。)

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

我在代码中写了我认为错误的地方(预测函数没有找到 mod_sim 对象)。它很可能在那里,因为 cat 就在这一行上面打印,而下面的那个不打印。

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

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

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)

无论如何我希望有人能帮助!

非常感谢!

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