dfmx {fmx} | R Documentation |
Density, Distribution and Quantile of Finite Mixture Distribution
Description
Density function, distribution function, quantile function and random generation for a finite mixture distribution
with normal or Tukey g
-&-h
components.
Usage
dfmx(
x,
dist,
distname = dist@distname,
K = dim(pars)[1L],
pars = dist@pars,
w = dist@w,
...,
log = FALSE
)
pfmx(
q,
dist,
distname = dist@distname,
K = dim(pars)[1L],
pars = dist@pars,
w = dist@w,
...,
lower.tail = TRUE,
log.p = FALSE
)
qfmx(
p,
dist,
distname = dist@distname,
K = dim(pars)[1L],
pars = dist@pars,
w = dist@w,
interval = qfmx_interval(dist = dist),
...,
lower.tail = TRUE,
log.p = FALSE
)
rfmx(
n,
dist,
distname = dist@distname,
K = dim(pars)[1L],
pars = dist@pars,
w = dist@w
)
Arguments
x , q |
|
dist |
fmx object, a finite mixture distribution |
distname , K , pars , w |
auxiliary parameters, whose default values are determined by argument |
... |
additional parameters |
log , log.p |
logical scalar.
If |
lower.tail |
logical scalar.
If |
p |
|
interval |
length two numeric vector, interval for root finding, see vuniroot2 and vuniroot |
n |
integer scalar, number of observations. |
Details
A computational challenge in function dfmx is when mixture density is very close to 0,
which happens when the per-component log densities are negative with big absolute values.
In such case, we cannot compute the log mixture densities (i.e., -Inf
),
for the log-likelihood using function logLik.fmx.
Our solution is to replace these -Inf
log mixture densities by
the weighted average (using the mixing proportions of dist
)
of the per-component log densities.
Function qfmx gives the quantile function, by numerically solving pfmx.
One major challenge when dealing with the finite mixture of Tukey g
-&-h
family distribution
is that Brent–Dekker's method needs to be performed in both pGH and qfmx functions,
i.e. two layers of root-finding algorithm.
Value
Function dfmx returns a numeric vector of probability density values of an fmx object at specified quantiles x
.
Function pfmx returns a numeric vector of cumulative probability values of an fmx object at specified quantiles q
.
Function qfmx returns an unnamed numeric vector of quantiles of an fmx object, based on specified cumulative probabilities p
.
Function rfmx generates random deviates of an fmx object.
Note
Function qnorm returns an unnamed vector of quantiles, although quantile returns a named vector of quantiles.
Examples
library(ggplot2)
(e1 = fmx('norm', mean = c(0,3), sd = c(1,1.3), w = c(1, 1)))
curve(dfmx(x, dist = e1), xlim = c(-3,7))
ggplot() + geom_function(fun = dfmx, args = list(dist = e1)) + xlim(-3,7)
ggplot() + geom_function(fun = pfmx, args = list(dist = e1)) + xlim(-3,7)
hist(rfmx(n = 1e3L, dist = e1), main = '1000 obs from e1')
x = (-3):7
round(dfmx(x, dist = e1), digits = 3L)
round(p1 <- pfmx(x, dist = e1), digits = 3L)
stopifnot(all.equal.numeric(qfmx(p1, dist = e1), x, tol = 1e-4))
(e2 = fmx('GH', A = c(0,3), g = c(.2, .3), h = c(.2, .1), w = c(2, 3)))
ggplot() + geom_function(fun = dfmx, args = list(dist = e2)) + xlim(-3,7)
round(dfmx(x, dist = e2), digits = 3L)
round(p2 <- pfmx(x, dist = e2), digits = 3L)
stopifnot(all.equal.numeric(qfmx(p2, dist = e2), x, tol = 1e-4))
(e3 = fmx('GH', g = .2, h = .01)) # one-component Tukey
ggplot() + geom_function(fun = dfmx, args = list(dist = e3)) + xlim(-3,5)
set.seed(124); r1 = rfmx(1e3L, dist = e3);
set.seed(124); r2 = TukeyGH77::rGH(n = 1e3L, g = .2, h = .01)
stopifnot(identical(r1, r2)) # but ?rfmx has much cleaner code
round(dfmx(x, dist = e3), digits = 3L)
round(p3 <- pfmx(x, dist = e3), digits = 3L)
stopifnot(all.equal.numeric(qfmx(p3, dist = e3), x, tol = 1e-4))
a1 = fmx('GH', A = c(7,9), B = c(.8, 1.2), g = c(.3, 0), h = c(0, .1), w = c(1, 1))
a2 = fmx('GH', A = c(6,9), B = c(.8, 1.2), g = c(-.3, 0), h = c(.2, .1), w = c(4, 6))
library(ggplot2)
(p = ggplot() +
geom_function(fun = pfmx, args = list(dist = a1), mapping = aes(color = 'g2=h1=0')) +
geom_function(fun = pfmx, args = list(dist = a2), mapping = aes(color = 'g2=0')) +
xlim(3,15) +
scale_y_continuous(labels = scales::percent) +
labs(y = NULL, color = 'models') +
coord_flip())
p + theme(legend.position = 'none')
# to use [rfmx] without \pkg{fmx}
(d = fmx(distname = 'GH', A = c(-1,1), B = c(.9,1.1), g = c(.3,-.2), h = c(.1,.05), w = c(2,3)))
d@pars
set.seed(14123); x = rfmx(n = 1e3L, dist = d)
set.seed(14123); x_raw = rfmx(n = 1e3L,
distname = 'GH', K = 2L,
pars = rbind(
c(A = -1, B = .9, g = .3, h = .1),
c(A = 1, B = 1.1, g = -.2, h = .05)
),
w = c(.4, .6)
)
stopifnot(identical(x, x_raw))