Skip to content

Commit 684524b

Browse files
committed
Fixes #468
1 parent ab570e9 commit 684524b

25 files changed

+199
-21
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export(util_logistic_stats_tbl)
121121
export(util_lognormal_aic)
122122
export(util_lognormal_param_estimate)
123123
export(util_lognormal_stats_tbl)
124+
export(util_negative_binomial_aic)
124125
export(util_negative_binomial_param_estimate)
125126
export(util_negative_binomial_stats_tbl)
126127
export(util_normal_aic)

NEWS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
None
55

66
## New Features
7-
None
7+
1. #468 - Add function `util_negative_binomial_aic()` to calculate the AIC for the negative binomial distribution.
88

99
## Minor Improvements and Fixes
10-
None
10+
1. Fix #468 - Update `util_negative_binomial_param_estimate()` to add the use of
11+
`optim()` for parameter estimation.
1112

1213
# TidyDensity 1.4.0
1314

R/est-param-negative-binomial.R

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
#' parameter `.x` will be run through the `tidy_empirical()` function and combined
1414
#' with the estimated negative binomial data.
1515
#'
16-
#' Two different methods of shape parameters are supplied:
16+
#' Three different methods of shape parameters are supplied:
1717
#' - MLE/MME
1818
#' - MMUE
19+
#' - MLE via \code{\link[stats]{optim}} function.
1920
#'
2021
#' @param .x The vector of data to be passed to the function.
21-
#' @param .size The size parameter.
22+
#' @param .size The size parameter, the default is 1.
2223
#' @param .auto_gen_empirical This is a boolean value of TRUE/FALSE with default
2324
#' set to TRUE. This will automatically create the `tidy_empirical()` output
2425
#' for the `.x` parameter and use the `tidy_combine_distributions()`. The user
@@ -45,7 +46,7 @@
4546
#' @export
4647
#'
4748

48-
util_negative_binomial_param_estimate <- function(.x, .size,
49+
util_negative_binomial_param_estimate <- function(.x, .size = 1,
4950
.auto_gen_empirical = TRUE) {
5051

5152
# Tidyeval ----
@@ -62,7 +63,7 @@ util_negative_binomial_param_estimate <- function(.x, .size,
6263

6364
# Checks ----
6465
if (!is.vector(x_term, mode = "numeric") || is.factor(x_term) ||
65-
!is.vector(size, mode = "numeric") || is.factor(size)) {
66+
!is.vector(size, mode = "numeric") || is.factor(size)) {
6667
rlang::abort(
6768
message = "'.x' and '.size' must be numeric vectors.",
6869
use_cli_format = TRUE
@@ -88,7 +89,7 @@ util_negative_binomial_param_estimate <- function(.x, .size,
8889
}
8990

9091
if (!all(x_term == trunc(x_term)) || any(x_term < 0) || !all(size == trunc(size)) ||
91-
any(size < 1)) {
92+
any(size < 1)) {
9293
rlang::abort(
9394
message = "All values of '.x' must be non-negative integers, and all values
9495
of '.size' must be positive integers.",
@@ -106,26 +107,47 @@ util_negative_binomial_param_estimate <- function(.x, .size,
106107
es_mvue_size <- size
107108
es_mvue_prob <- (size - 1) / (size + sum_x - 1)
108109

110+
# MLE Method
111+
# Negative log-likelihood function for optimization
112+
nll_func <- function(params) {
113+
size <- params[1]
114+
mu <- params[2]
115+
-sum(dnbinom(x, size = size, mu = mu, log = TRUE))
116+
}
117+
118+
# Initial parameter guesses (you might need to adjust these based on your data)
119+
initial_params <- c(size = 1, mu = mean(x))
120+
121+
# Optimize using optim()
122+
optim_result <- optim(initial_params, nll_func)
123+
124+
# Extract estimated parameters
125+
mle_size <- optim_result$par[1]
126+
mle_mu <- optim_result$par[2]
127+
mle_prob <- mle_size / (mle_size + mle_mu)
128+
109129
# Return Tibble ----
110130
if (.auto_gen_empirical) {
111131
te <- tidy_empirical(.x = x_term)
112132
td <- tidy_negative_binomial(
113-
.n = n, .size = round(es_mme_size, 3),
114-
.prob = round(es_mme_prob, 3)
133+
.n = n, .size = round(mle_size, 3),
134+
.prob = round(mle_prob, 3)
115135
)
116136
combined_tbl <- tidy_combine_distributions(te, td)
117137
}
118138

119139
ret <- dplyr::tibble(
120-
dist_type = rep("Negative Binomial", 2),
121-
samp_size = rep(n, 2),
122-
min = rep(minx, 2),
123-
max = rep(maxx, 2),
124-
mean = rep(m, 2),
125-
method = c("EnvStats_MME_MLE", "EnvStats_MMUE"),
126-
size = c(es_mme_size, es_mvue_size),
127-
prob = c(es_mme_prob, es_mvue_prob),
128-
shape_ratio = c(es_mme_size / es_mme_prob, es_mvue_size / es_mvue_prob)
140+
dist_type = rep("Negative Binomial", 3),
141+
samp_size = rep(n, 3),
142+
min = rep(minx, 3),
143+
max = rep(maxx, 3),
144+
mean = c(rep(m, 2), mle_mu),
145+
method = c("EnvStats_MME_MLE", "EnvStats_MMUE", "MLE_Optim"),
146+
size = c(es_mme_size, es_mvue_size, mle_size),
147+
prob = c(es_mme_prob, es_mvue_prob, mle_prob),
148+
shape_ratio = c(es_mme_size / es_mme_prob,
149+
es_mvue_size / es_mvue_prob,
150+
mle_size / mle_prob)
129151
)
130152

131153
# Return ----

R/utils-aic-negative-binomial.R

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#' Calculate Akaike Information Criterion (AIC) for Negative Binomial Distribution
2+
#'
3+
#' This function calculates the Akaike Information Criterion (AIC) for a negative binomial distribution fitted to the provided data.
4+
#'
5+
#' @family Utility
6+
#' @author Steven P. Sanderson II, MPH
7+
#'
8+
#' @description
9+
#' This function estimates the parameters size (r) and probability (prob) of a
10+
#' negative binomial distribution from the provided data and then calculates
11+
#' the AIC value based on the fitted distribution.
12+
#'
13+
#' @param .x A numeric vector containing the data to be fitted to a negative
14+
#' binomial distribution.
15+
#'
16+
#' @details
17+
#' This function fits a negative binomial distribution to the provided data.
18+
#' It estimates the parameters size (r) and probability (prob) of the negative
19+
#' binomial distribution from the data. Then, it calculates the AIC value based
20+
#' on the fitted distribution.
21+
#'
22+
#' Initial parameter estimates: The function uses the method of moments estimate
23+
#' as a starting point for the size (r) parameter of the negative binomial distribution,
24+
#' and the probability (prob) is estimated based on the mean and variance of the data.
25+
#'
26+
#' Optimization method: Since the parameters are directly calculated from the data,
27+
#' no optimization is needed.
28+
#'
29+
#' Goodness-of-fit: While AIC is a useful metric for model comparison, it's
30+
#' recommended to also assess the goodness-of-fit of the chosen model using
31+
#' visualization and other statistical tests.
32+
#'
33+
#' @examples
34+
#' # Example 1: Calculate AIC for a sample dataset
35+
#' set.seed(123)
36+
#' data <- rnbinom(n = 100, size = 5, mu = 10)
37+
#' util_negative_binomial_aic(data)
38+
#'
39+
#' @return
40+
#' The AIC value calculated based on the fitted negative binomial distribution to the provided data.
41+
#'
42+
#' @name util_negative_binomial_aic
43+
NULL
44+
45+
#' @export
46+
#' @rdname util_negative_binomial_aic
47+
util_negative_binomial_aic <- function(.x) {
48+
# Tidyeval
49+
x <- as.numeric(.x)
50+
51+
# Estimate size (r) parameter using method of moments
52+
m <- mean(x)
53+
v <- var(x)
54+
r <- m^2 / (v - m)
55+
56+
# Estimate probability (prob) parameter
57+
prob <- r / (r + m)
58+
59+
# Calculate AIC
60+
k_negative_binomial <- 2 # Number of parameters for negative binomial distribution (r and prob)
61+
logLik_negative_binomial <- sum(dnbinom(x, size = r, prob = prob, log = TRUE))
62+
AIC_negative_binomial <- 2 * k_negative_binomial - 2 * logLik_negative_binomial
63+
64+
# Return AIC
65+
return(AIC_negative_binomial)
66+
}

man/check_duplicate_rows.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/convert_to_ts.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/quantile_normalize.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/tidy_mcmc_sampling.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/util_beta_aic.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/util_binomial_aic.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)