如何 return 在函数中创建的对象并忽略带有 error/NA 的对象?

How to return objects created in a function and ignore the ones with error/NA?

我已经编辑了我的问题

目标

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

例子

请注意,这只是一个可重现的示例。我的原始数据集不同。

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

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 成功匹配。

我想 return 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 安静地 return 一个合适的结果或抛出错误而不在错误处停止。但我不知道如何 return 仅在 gofstat.

中成功拟合值

您可以用单个 lapply 替换单个列表子集。如果您将此设置为 return 和 NULL 而不是 NA,该条目将在取消列出后消失。因此,以下函数将执行您想要的操作,如此表示所示:

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 创建

你可以试试 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 创建