Issue fitting lognormal 3 parameters with fitdistrplus using mme

56 Views Asked by At

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)
    }
})>
0

There are 0 best solutions below