hi folks,
I am trying to calculate the 3-parameter Gamma distribution in R using several methods. I am able to produce results, but the estimated shape, scale, and threshold (location) values do not match the results provided by Minitab. Can anyone help me understand why this is happening and how to align the R results with Minitab?
here is my dataset
x <- c(1.2, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.6, 3.0, 3.5, 4.0, 4.8, 5.6, 6.6, 7.6)
minitab Result
#-----------------------
#Shape: 2.37046
#scale: 1.19117
#Threshold: 0.51634
#-----------------------------------------------------
# Method-1
# 3-parameter Gamma Negative Log-Likelihood
#-----------------------------------------------------
negloglik_gamma3 <- function(params, data) {
shape <- params[1]
scale <- params[2]
shift <- params[3]
y <- data - shift
if (shape <= 0 || scale <= 0 || any(y <= 0)) return(1e10)
-sum(dgamma(y, shape = shape, scale = scale, log = TRUE))
}
x_moments <- x - min(x) + 0.01
init_shape <- mean(x_moments)^2 / var(x_moments)
init_scale <- var(x_moments) / mean(x_moments)
init_shift <- min(x) - 0.5
init_params <- c(shape = init_shape, scale = init_scale, shift = init_shift)
lower_bounds <- c(1e-4, 1e-4, -Inf)
upper_bounds <- c(Inf, Inf, min(x) - 1e-6)
fit <- optim(par = init_params,
fn = negloglik_gamma3,
data = x,
method = "L-BFGS-B",
lower = lower_bounds,
upper = upper_bounds,
control = list(fnscale = 1))
shape_est <- fit$par[1]
scale_est <- fit$par[2]
shift_est <- fit$par[3]
cat("Estimated shape:", round(shape_est, 5), "\n")
cat("Estimated scale:", round(scale_est, 5), "\n")
cat("Estimated shift:", round(shift_est, 5), "\n")
#-----------------------------------------------------
#Result of method 1
#-----------------------------------------------------
# Estimated shape: 0.50503
# Estimated scale: 4.23743
# Estimated shift: 1.2
#------------------------------------------------------
# Method 2
#-----------------------------------------------------
library(FAdist);
library(fitdistrplus)
fit<-fitdist(x,dgamma3,start=list(shape=1,scale=1,thres=0.5),
upper=c(Inf,Inf,min(x)))
print(fit)
#-----------------------------------------------------------
# Result of method 2
#----------------------------------------------------------
#shape : 0.2922451
#scale : 7.3236
#thres : 1.2
#---------------------------------------------------------
#-----------------------------------------------------------
#---Method 3
#-----------------------------------------------------------
theta_vals <- seq(min(x) - 1, min(x) - 0.01, length.out = 100)
best_ll <- -Inf
best_params <- NULL
for (theta in theta_vals) {
shifted_data <- x - theta
if (any(shifted_data <= 0)) next
sample_mean <- mean(shifted_data)
sample_var <- var(shifted_data)
shape_est <- sample_mean^2 / sample_var
scale_est <- sample_var / sample_mean
loglik <- sum(dgamma(shifted_data, shape = shape_est, scale = scale_est, log = TRUE))
if (loglik > best_ll) {
best_ll <- loglik
best_params <- c(shape = shape_est, scale = scale_est, threshold = theta)
}
}
cat("Best Estimates:\n")
cat("Shape (alpha):", best_params[1], "\n")
cat("Scale (beta):", best_params[2], "\n")
cat("Threshold (theta):", best_params[3], "\n")
#---------------------------------------------------------
# Result of method 3
#---------------------------------------------------------
# Shape (alpha): 1.199152
# Scale (beta): 1.809612
# Threshold (theta): 1.17
#---------------------------------------------------------
thanks in advance.