如何返回在函数中创建的对象并忽略具有错误/ NA的对象?

问题描述

我已经编辑了问题

目标

我只想保留那些成功创建的对象,而忽略那些引发错误的对象。

示例

请注意,这只是一个可复制的示例。我的原始数据集不一样。

以下函数采用mtcars数据集的任何变量,拟合三个理论分布,然后返回拟合统计的优度:

library(fitdistrplus)

fit_distt <- function(var) {
  
v <- mtcars[,var]
  
f1 <- fitdist(data = v,distr = "norm")

f2 <- fitdist(data = v,distr = "nbinom")

f3 <- fitdist(data = v,distr = "gamma")

gofstat(f = list(f1,f2,f3),chisqbreaks = c(0,3,3.5,4,4.5,5,10,20,30,40),fitnames = c("normal","nbinom","gamma"))

}

例如:

> fit_distt("gear")
Goodness-of-fit statistics
                                normal    nbinom     gamma
Kolmogorov-Smirnov statistic 0.2968616 0.4967268 0.3030232
Cramer-von Mises statistic   0.4944390 1.5117544 0.5153004
Anderson-Darling statistic   3.1060083 7.2858460 3.1742713

Goodness-of-fit criteria
                                 normal   nbinom    gamma
Akaike's information Criterion 74.33518 109.9331 72.07507
Bayesian information Criterion 77.26665 112.8646 75.00655

问题

某些理论分布不能成功地适合变量,并且fitdist会引发错误

> fit_distt("mpg")
<simpleError in optim(par = vstart,fn = fnobj,fix.arg = fix.arg,obs = data,gr = gradient,ddistnam = ddistname,hessian = TRUE,method = meth,lower = lower,upper = upper,...): function cannot be evaluated at initial parameters>
 Error in fitdist(data = v,distr = "nbinom") : 
  the function mle Failed to estimate the parameters,with the error code 100 

f2发生此错误,试图使nbinom适合连续变量mpg。但是normgamma成功地适合了。

我想返回gofstat来成功拟合分布,而忽略那些引发错误的分布。

预期产量

即使在函数中指定了f2,但如果抛出错误,我仍然需要以下输出

> fit_distt("mpg")
Goodness-of-fit statistics
                                 normal      gamma
Kolmogorov-Smirnov statistic 0.12485059 0.08841088
Cramer-von Mises statistic   0.08800019 0.03793323
Anderson-Darling statistic   0.58886727 0.28886166

Goodness-of-fit criteria
                                 normal    gamma
Akaike's information Criterion 208.7555 205.8416
Bayesian information Criterion 211.6870 208.7731

我尝试过的

很显然,我可以从函数删除f2。但这意味着对每个变量重复所有代码。大量的代码!因此,我仍然想使用该功能

我希望能够对任何变量使用该函数。对于mtcars$mpg,该功能对于nbinom失败,但是对于mtcars$vs,该功能对于gamma失败。无论如何,我都想跳过引发错误的拟合,并报告gofstat以了解有效的拟合。

我可以使用purrr::possibly悄悄地返回拟合结果或抛出错误而不会停止错误。但是我不知道如何仅在gofstat中返回成功拟合的值。

解决方法

您可以尝试使用try。尝试调整分布并将其添加到传递给gofstat的列表中(如果可行)

library(fitdistrplus)
#> Loading required package: MASS
#> Loading required package: survival


fit_distt <- function(var) {
  
  v <- mtcars[,var]
  
  distributions <- c("norm","nbinom","gamma")
  
  fs <- list()
  fitted_distributions <- vector(mode = "character")
  for (i in seq_along(distributions)) {
    # try to fit the model
    fit <- try(fitdist(data = v,distr = distributions[i]),silent = TRUE)    
    
    # if it works,add it to fs. If not,¯\_(ツ)_/¯
    if (!inherits(fit,"try-error")) {
      fs[[length(fs)+1]] <- fit
      fitted_distributions[length(fitted_distributions)+1] <-  distributions[i]
    }
  }
  
  gofstat(f = fs,chisqbreaks = c(0,3,3.5,4,4.5,5,10,20,30,40),fitnames = fitted_distributions)
  
}

fit_distt("mpg")
#> <simpleError in optim(par = vstart,fn = fnobj,fix.arg = fix.arg,obs = data,gr = gradient,ddistnam = ddistname,hessian = TRUE,method = meth,lower = lower,upper = upper,...): function cannot be evaluated at initial parameters>
#> Goodness-of-fit statistics
#>                                    norm      gamma
#> Kolmogorov-Smirnov statistic 0.12485059 0.08841088
#> Cramer-von Mises statistic   0.08800019 0.03793323
#> Anderson-Darling statistic   0.58886727 0.28886166
#> 
#> Goodness-of-fit criteria
#>                                    norm    gamma
#> Akaike's Information Criterion 208.7555 205.8416
#> Bayesian Information Criterion 211.6870 208.7731

reprex package(v0.3.0)于2020-10-07创建

,

您可以将单个列表子集替换为一个lapply。如果您得到此返回一个NULL而不是NA,则该条目将在不列出后消失。因此,下面的函数将执行您想要的操作,如此reprex中所示:

find_mean_of_each_vector_in_a_list <- function(my_list) {
 suppressWarnings(
   as.numeric(
     unlist(
       sapply(my_list,function(x) if(is.na(mean(x))) NULL else mean(x))
       )))
}

my_list_1 <- list(a = 1:3,b = 5:6,c = 7:10)
my_list_2 <- list(a = 1:3,b = c("a","b"),c = 7:10)

find_mean_of_each_vector_in_a_list(my_list_1)
#> [1] 2.0 5.5 8.5
find_mean_of_each_vector_in_a_list(my_list_2)
#> [1] 2.0 8.5

reprex package(v0.3.0)于2020-10-07创建