I have been trying to ajust a 3-parameters log-normal distribution by moments matching (mme) using two libraries: fitdistrplus and EnvStats but after many attemps I still get errors. The reason I use fitdistrplus is that I would like to produce confidence intervals for the resulting quantiles. Does anyone had the same issue and solved it? Bellow is the code I have writen. Thanks in advance!
library(fitdistrplus)
library(EnvStats)
y # discharge sample
# density, probability and quantile functions (from EnvStats library)
dln3<-function(x,meanlog,sdlog,threshold){dlnorm3(x,meanlog,sdlog,threshold)}
pln3<-function(q,meanlog,sdlog,threshold){plnorm3(q,meanlog,sdlog,threshold)}
qln3<-function(p,meanlog,sdlog,threshold){qlnorm3(p,meanlog,sdlog,threshold)}
# initial parameters (from EnvStats library)
param<-elnorm3(y, method = "mme", ci = FALSE, ci.parameter = FALSE,
ci.method = FALSE, ci.type = FALSE, conf.level = FALSE,
threshold.lb.sd = 100, evNormOrdStats.method = "royston")
param<-param$parameters
# centered empirical moments
memp<-function(x,order){
n<-length(x)
s<-(var(x))^0.5
if(order==1){return(memp<-mean(x))}
else if(order==2){return(memp<-(var(x))^0.5)}
else if(order==3){return(memp<-n/((n-1)*(n-2))*sum((x-mean(x))^3)/s^3)}
}
# centered distribution moments
mln3<-function(order,meanlog,sdlog,threshold){
if(order==1){return(threshold+exp(1)^(meanlog+sdlog^2/2))}
else if(order==2){return(((exp(1)^(sdlog^2)-1)*exp(1)^(2*meanlog+sdlog^2))^0.5)}
else if(order==3){return((exp(1)^sdlog^2+2)*(exp(1)^sdlog^2-1)^0.5)}
}
# fitting the distribution using fitdistrplus
ajust<-fitdistrplus::fitdist(y,distr="ln3",method="mme",memp=memp,mln3=mln3,
order=1:3,start=list(meanlog=param[[1]],sdlog=param[[2]],
threshold=param[[3]]))
The error I get is:
<simpleError in fn(par, ...): unused argument (mln3 = function (order, meanlog, sdlog, threshold)
{
if (order == 1) {
return(threshold + exp(1)^(meanlog + sdlog^2/2))
} else if (order == 2) {
return(((exp(1)^(sdlog^2) - 1) * exp(1)^(2 * meanlog + sdlog^2))^0.5)
} else if (order == 3) {
return((exp(1)^sdlog^2 + 2) * (exp(1)^sdlog^2 - 1)^0.5)
}
})>