Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fitting a lognormal distribution to truncated data in R

Tags:

r

distribution

For a brief background, I am insterested in describing a distribution of fire sizes, which is presumed to follow a lognormal distribution (many small fires and few large fires). For my specific application I am only interested in the fires that fall within a certain range of sizes (> min, < max). So, I am attempting to fit a lognormal distribution to a data set that has been censored on both ends. In essence, I want to find the parameters of the lognormal distribution (mu and sigma) that best fits the full distribution prior to censoring. Can I fit the distribution taking into account that I know I am only looking a a portion of the distribution?

I have done some experimentation, but have become stumped. Here's an example:

# Generate data #
D <- rlnorm(1000,meanlog = -0.75, sdlog = 1.5)
# Censor data #
min <- 0.10
max <- 20
Dt <- D[D > min]
Dt <- Dt[Dt <= max]

If I fit the non-censored data (D) using either fitdistr (MASS) or fitdist (fitdistrplus) I obviously get approximately the same parameter values as I entered. But if I fit the censored data (Dt) then the parameter values do not match, as expected. The question is how to incorporate the known censoring. I have seen some references elsewhere to using upper and lower within fitdistr, but I encounter an error that I'm not sure how to resolve:

> fitt <- fitdist(Dt, "lognormal", lower = min, upper = max)
Error in fitdist(Dt, "lognormal", lower = min, upper = max) : 
The  dlognormal  function must be defined 

I will appreciate any advice, first on whether this is the appropriate way to fit a censored distribution, and if so, how to go about defining the dlognormal function so that I can make this work. Thanks!

like image 702
B Miranda Avatar asked Dec 05 '22 10:12

B Miranda


1 Answers

Your data is not censored (that would mean that observations outside the interval are there, but you do not know their exact value) but truncated (those observations have been discarded).

You just have to provide fitdist with the density and the cumulative distribution function of your truncated distribution.

library(truncdist)
dtruncated_log_normal <- function(x, meanlog, sdlog) 
  dtrunc(x, "lnorm", a=.10, b=20, meanlog=meanlog, sdlog=sdlog)
ptruncated_log_normal <- function(q, meanlog, sdlog) 
  ptrunc(q, "lnorm", a=.10, b=20, meanlog=meanlog, sdlog=sdlog)

library(fitdistrplus)
fitdist(Dt, "truncated_log_normal", start = list(meanlog=0, sdlog=1))
# Fitting of the distribution ' truncated_log_normal ' by maximum likelihood 
# Parameters:
#           estimate Std. Error
# meanlog -0.7482085 0.08390333
# sdlog    1.4232373 0.0668787
like image 75
Vincent Zoonekynd Avatar answered Jan 08 '23 04:01

Vincent Zoonekynd