如何 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
上。但是 norm
和 gamma
成功匹配。
我想 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 创建
我已经编辑了我的问题
目标
我只想保留那些成功创建的对象,忽略那些抛出错误的对象。
例子
请注意,这只是一个可重现的示例。我的原始数据集不同。
以下函数采用 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
上。但是 norm
和 gamma
成功匹配。
我想 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 创建