问题描述
我已经编辑了问题
目标
我只想保留那些成功创建的对象,而忽略那些引发错误的对象。
示例
请注意,这只是一个可复制的示例。我的原始数据集不一样。
以下函数采用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
。但是norm
和gamma
成功地适合了。
我想返回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创建