| Type: | Package |
| Title: | Fit Two-Component Normal and Lognormal Mixture Models |
| Version: | 0.3.0 |
| Description: | Fits, bootstraps, and evaluates two-component normal and lognormal mixture models. Parameters are searched within data-derived bounds by differential-evolution global optimization, as implemented in the 'DEoptim' package (Mullen, Ardia, Gil, Windover and Cline, 2011) <doi:10.18637/jss.v040.i06>, followed by a local 'L-BFGS-B' refinement step via optim(). Also provides preliminary diagnostic plots, diagnostic plots for fitted mixtures, automatic normal-versus-lognormal model selection by the Bayesian or Akaike information criterion, and parametric or nonparametric bootstrap confidence intervals for the fitted parameters. |
| Depends: | R (≥ 4.0.0) |
| Imports: | DEoptim (≥ 2.0.0), pbapply (≥ 1.0.0), graphics, stats, utils |
| License: | MIT + file LICENSE |
| URL: | https://github.com/FHabibzadeh/DEmixR |
| BugReports: | https://github.com/FHabibzadeh/DEmixR/issues |
| Encoding: | UTF-8 |
| Suggests: | knitr, rmarkdown, testthat (≥ 3.1.7), parallelly |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Config/roxygen2/version: | 8.1.0 |
| Packaged: | 2026-09-25 05:47:50 UTC; mac |
| Author: | Farrokh Habibzadeh
|
| Maintainer: | Farrokh Habibzadeh <farrokh.habibzadeh@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-25 06:10:02 UTC |
Core two-component mixture fitter (differential evolution + local refinement)
Description
Workhorse behind fit_norm2 and fit_lognorm2. Runs
one or more differential-evolution searches via DEoptim inside the
bounds returned by mix2_bounds and then refines the best
candidate with a local "L-BFGS-B" optim step.
Not exported; the tuning arguments documented here are the ones users
pass through the ... of the exported fit functions.
Usage
.fit_mix2_core(
x,
family = c("lognormal", "normal"),
lower = NULL,
upper = NULL,
NP = 100,
itermax = 10000,
reltol = 5e-06,
steptol = 50,
F = 0.8,
CR = 0.9,
strategy = 2,
parallelType = 0,
packages = c("stats"),
parVar = NULL,
n_runs = 10,
quiet = 2,
par_init = NULL,
pgtol = 1e-08,
scale_range = c(0.1, 10),
p_range = c(0.001, 0.999),
scale_ratio = 0,
min_comp_n = 5
)
Arguments
x |
numeric data vector (strictly positive when
|
family |
character; either |
lower, upper |
optional numeric vectors of length 5 giving box
constraints for the parameters |
NP |
DEoptim population size. |
itermax |
maximum number of DEoptim iterations per run. |
reltol, steptol |
DEoptim convergence controls (relative tolerance and the number of stall iterations allowed before stopping). |
F, CR, strategy |
DEoptim differential-weighting, crossover-probability,
and strategy controls (see |
parallelType |
passed to |
packages, parVar |
passed to |
n_runs |
number of independent DEoptim runs (default 10); the run with the best objective is refined locally. |
quiet |
verbosity: |
par_init |
optional numeric vector of length 5 giving user starting values for an additional local optimization, compared against the DE-based solution. |
pgtol |
projected-gradient tolerance for the |
scale_range, p_range |
multiplicative limits of the component standard
deviations and range of the mixing proportion used to build the default
bounds; see |
scale_ratio |
optional Hathaway-type relative constraint on the two
component standard deviations, |
min_comp_n |
a warning is issued when the expected size of a component
(the sum of its posterior probabilities over all observations, about
|
Value
An object of class demixr_fit (see fit_norm2).
Bootstrap mixture parameters
Description
Parametric or nonparametric bootstrap of the five parameters of a fitted two-component mixture, with percentile confidence intervals.
Usage
bootstrap_mix2(
fit = NULL,
x = NULL,
par = NULL,
family = NULL,
B = 1000,
parametric = TRUE,
boot_size = NULL,
parallelType = 0,
quiet = 2,
ci_level = 0.95,
refit = c("local", "de"),
center = c("median", "mean"),
de_control = list(),
scale_ratio = NULL
)
Arguments
fit |
fitted object from fit_lognorm2 or fit_norm2 |
x |
numeric vector (if fit not provided) |
par |
numeric vector of parameters (if fit not provided) |
family |
"lognormal" or "normal" (if fit not provided) |
B |
number of bootstrap replicates |
parametric |
logical, parametric bootstrap if TRUE |
boot_size |
size or fraction (if between 0 and 1) of bootstrap sample |
parallelType |
values 0 or 1 run serially. An integer greater than 1 is
passed to |
quiet |
0/1/2 for verbosity (0 suppresses the progress bar) |
ci_level |
confidence level |
refit |
|
center |
summary reported in |
de_control |
list of DE settings used when |
scale_ratio |
relative scale constraint, taken from |
Details
Two refitting strategies are available. With refit = "local" (the
default, fast) every replicate is refitted by a local L-BFGS-B
optimization started at the original estimate. This does not repeat
the global search, so it does not propagate uncertainty arising from
multimodality of the likelihood: a replicate whose likelihood has a
different dominant mode may be pulled back to the original solution.
With refit = "de" every replicate is refitted with the same
procedure as the original fit (a differential-evolution search followed by
L-BFGS-B; the DE settings are controlled by de_control); this is
much slower. Percentile intervals of mixture parameters can behave poorly
with weakly separated components, small mixing proportions or solutions on
the bounds; their coverage should not be taken for granted.
Value
an object of class demixr_boot: a list with the converged
bootstrap estimates (ests_clean), the chosen summary
(central), the mean and median, percentile
confidence intervals (ci), the number of converged
(n_success) and failed (n_failed) replicates and the
refit strategy. Has a print method.
Reproducibility
No seed argument is provided. Call
set.seed() before the call for reproducible resampling
(only guaranteed for parallelType 0 or 1, i.e. serial execution;
forked workers do not generally reproduce from a single seed).
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
boot <- bootstrap_mix2(fit, B = 20, quiet = 0)
boot
Evaluate initial parameter values for mixture fitting
Description
Runs a single L-BFGS-B optimization from the supplied starting values inside the same bounds used by the fitting functions.
Usage
evaluate_init(
par_init,
x,
family = c("lognormal", "normal"),
lower = NULL,
upper = NULL,
pgtol = 1e-08,
scale_ratio = 0
)
Arguments
par_init |
numeric vector of initial parameters (p, m1, s1, m2, s2) |
x |
numeric vector of data |
family |
"lognormal" or "normal" |
lower |
numeric vector of lower bounds |
upper |
numeric vector of upper bounds |
pgtol |
numeric, gradient tolerance for optim |
scale_ratio |
relative scale constraint, see |
Value
list with success flag (TRUE when L-BFGS-B reports
convergence code 0), the optimized parameters (ordered so that
m1 <= m2), log-likelihood, and convergence code and message
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
ev <- evaluate_init(par_init = c(0.7, 0, 1, 4, 1), x = x, family = "normal")
ev$success
Fit 2-component lognormal mixture
Description
Finds the best two-component lognormal mixture inside the bounded parameter
region returned by mix2_bounds, by differential evolution
followed by an L-BFGS-B refinement. The result is the best solution found
within those bounds, not a global maximum of the unrestricted
likelihood (which is unbounded). The parameters m1, s1, m2, s2 are
the meanlog and sdlog of each component; components are
ordered so that m1 <= m2.
Usage
fit_lognorm2(x, ...)
Arguments
x |
numeric vector of data to fit (positive, finite, at least 10 observations) |
... |
additional arguments passed to |
Value
an object of class demixr_fit: a list with the fitted
parameters (par), logLik, AIC, BIC,
convergence information (convergence, source,
local_convergence), the bounds used, the log-likelihood reached by
each DE run (de_logLik) and diagnostics. Has print,
summary, and plot methods.
See Also
Examples
set.seed(1)
x <- c(rlnorm(150, 0, 0.5), rlnorm(50, 2, 0.3))
fit <- fit_lognorm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
fit
plot(fit)
Fit 2-component normal mixture
Description
Finds the best two-component normal mixture inside the bounded parameter
region returned by mix2_bounds, by differential evolution
followed by an L-BFGS-B refinement. The result is the best solution found
within those bounds, not a global maximum of the unrestricted
likelihood (which is unbounded for component-specific variances).
Components are ordered so that m1 <= m2.
Usage
fit_norm2(x, ...)
Arguments
x |
numeric vector of data to fit (finite, at least 10 observations) |
... |
additional arguments passed to |
Value
an object of class demixr_fit: a list with the fitted
parameters (par), logLik, AIC, BIC,
convergence information (convergence, source,
local_convergence), the bounds used, the log-likelihood reached by
each DE run (de_logLik) and diagnostics. Has print,
summary, and plot methods.
See Also
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
fit
plot(fit)
Parameter bounds used by the DEmixR fitting functions
Description
DEmixR does not maximize the likelihood over the whole natural parameter
space. The likelihood of a heteroscedastic normal (or lognormal) mixture is
unbounded – a component can collapse onto a single observation – so the
differential-evolution search and the local refinement are carried out
inside a box whose limits are derived from the data. mix2_bounds()
returns that box so that it can be inspected, modified and passed back to
fit_norm2 / fit_lognorm2 through lower and
upper.
Usage
mix2_bounds(
x,
family = c("normal", "lognormal"),
scale_range = c(0.1, 10),
p_range = c(0.001, 0.999)
)
Arguments
x |
numeric vector of data (strictly positive for
|
family |
|
scale_range |
numeric length 2; lower and upper limits of the component standard deviations, expressed as multiples of the sample standard deviation on the model's working scale (the original scale for the normal family and the log scale for the lognormal family). |
p_range |
numeric length 2; lower and upper limit of the mixing
proportion |
Details
For a normal mixture, with s_x the sample standard deviation of
x, the default limits are
mixing proportion
p:p_range(default 0.001 to 0.999);component means
m_1, m_2:[\min(x) - 2 s_x, \max(x)]and[\min(x), \max(x) + 2 s_x], respectively. The two means are not restricted to opposite sides of the median; component labels are assigned after estimation by ordering the means;component standard deviations:
s_xtimesscale_range(default 0.1 to 10).
For a lognormal mixture the same construction is applied on the log scale
(y = \log x, s_y = sd(y)), with the mean limits
padded by 2 log units instead of 2 s_x. The parameters m_j and
s_j of the lognormal model are the meanlog and sdlog
of component j.
Because of these limits the fitted values are the best solution found within the box, not a global maximum of the unrestricted likelihood. The factors 0.1 and 10 are pragmatic regularization choices; a solution that lies on a bound (reported by the fitting functions) indicates that the bounds, not the data, determined that estimate.
A relative constraint on the ratio of the component scales (Hathaway, 1985)
is available separately through the scale_ratio argument of the
fitting functions.
Value
A list with numeric vectors lower and upper (named
p, m1, s1, m2, s2).
References
Hathaway, R. J. (1985). A constrained formulation of maximum-likelihood estimation for normal mixture distributions. The Annals of Statistics, 13(2), 795-800.
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
mix2_bounds(x, "normal")
# tighter scale bounds
mix2_bounds(x, "normal", scale_range = c(0.2, 5))
Plot a fitted DEmixR mixture model
Description
Three views of a fitted mixture: the fitted density over a histogram
(which = "density", default), the histogram of the probability
integral transform ("pit"; approximately uniform when the fitted
mixture describes the data; the fit is evaluated on the same data it was
estimated from), and a Q-Q plot of the data against the quantiles of the
fitted mixture ("qq").
Usage
## S3 method for class 'demixr_fit'
plot(
x,
hist_bins = 60,
col_hist = "gray85",
col_total = "black",
col_comp1 = "steelblue",
col_comp2 = "firebrick",
which = c("density", "pit", "qq"),
...
)
Arguments
x |
an object of class |
hist_bins |
number of histogram bins |
col_hist |
histogram fill color |
col_total |
color of the fitted overall mixture density |
col_comp1 |
color of the first fitted component density |
col_comp2 |
color of the second fitted component density |
which |
|
... |
further arguments passed to |
Value
no return value, called for side effects (generating a plot)
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
plot(fit)
plot(fit, which = "pit")
plot(fit, which = "qq")
Preliminary diagnostic plots
Description
Exploratory displays of the data before fitting. The Q-Q and P-P panels
compare the data with a single normal (or lognormal, for the
"log" panels) distribution. A two-component mixture is not itself
normal, so curvature in these plots is expected and they do not validate or
refute the assumed component family. To assess a fitted mixture use
plot(fit, which = "pit") or plot(fit, which = "qq").
Usage
prelim_plots(
x,
which = c("hist"),
hist_bins = 60,
col_hist = "gray85",
col_density = "darkorange",
col_qq = "gray60",
col_line = "darkorange"
)
Arguments
x |
numeric vector |
which |
character vector: "hist", "qq", "pp", "logqq", "logpp" |
hist_bins |
number of bins for histogram |
col_hist |
color for histogram |
col_density |
color for the kernel-density curve drawn over the
histogram. Set to |
col_qq |
color for qq points |
col_line |
color for lines in "qq", "pp", "logqq" plots |
Value
no return value, called for side effects (generating plots)
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
prelim_plots(x, c("hist", "qq"), hist_bins = 15)
# Histogram without the kernel-density overlay (title becomes "Histogram")
prelim_plots(x, "hist", col_density = NA)
Print bootstrap results from a DEmixR mixture fit
Description
Print bootstrap results from a DEmixR mixture fit
Usage
## S3 method for class 'demixr_boot'
print(x, digits = 4, ...)
Arguments
x |
an object of class |
digits |
number of significant digits to print |
... |
further arguments passed to or from other methods (currently unused) |
Value
x, invisibly
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
boot <- bootstrap_mix2(fit, B = 20, quiet = 0)
print(boot)
Print a fitted DEmixR mixture model
Description
Print a fitted DEmixR mixture model
Usage
## S3 method for class 'demixr_fit'
print(x, digits = 4, ...)
Arguments
x |
an object of class |
digits |
number of significant digits to print |
... |
further arguments passed to or from other methods (currently unused) |
Value
x, invisibly
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
print(fit)
Print model-selection results from DEmixR
Description
Print model-selection results from DEmixR
Usage
## S3 method for class 'demixr_select'
print(x, digits = 4, ...)
Arguments
x |
an object of class |
digits |
number of significant digits to print |
... |
further arguments passed to or from other methods (currently unused) |
Value
x, invisibly
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
mix <- select_best_mixture(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
print(mix)
Print a summary of a fitted DEmixR mixture model
Description
Print a summary of a fitted DEmixR mixture model
Usage
## S3 method for class 'summary.demixr_fit'
print(x, digits = 4, ...)
Arguments
x |
an object of class |
digits |
number of significant digits to print |
... |
further arguments passed to or from other methods (currently unused) |
Value
x, invisibly
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
print(summary(fit))
Select best mixture model (lognormal or normal) based on AIC or BIC
Description
Fits a two-component normal mixture and, if all observations are positive,
a two-component lognormal mixture, and returns the family with the lower
information criterion. Both densities are defined on the original scale of
x, so their likelihoods and information criteria are comparable.
When x contains non-positive values the lognormal family is not
possible and the choice is dictated by the support of the data, not by
the criterion.
Usage
select_best_mixture(
x,
n_runs = 10,
NP = 100,
itermax = 10000,
quiet = 2,
criterion = c("BIC", "AIC"),
...
)
Arguments
x |
numeric vector |
n_runs |
number of DEoptim runs (default 10, as in
|
NP |
population size for DEoptim (default 100, as in
|
itermax |
maximum iterations |
quiet |
verbosity |
criterion |
|
... |
further arguments passed to |
Value
an object of class demixr_select: a list with the
best-fitting model (best), all fitted models (all), the
BIC of each (BICs), the AIC of each (AICs), the
criterion used and best_family. Has a print method.
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
mix <- select_best_mixture(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
mix
mix$best$family
Summarize a fitted DEmixR mixture model
Description
Summarize a fitted DEmixR mixture model
Usage
## S3 method for class 'demixr_fit'
summary(object, ...)
Arguments
object |
an object of class |
... |
further arguments passed to or from other methods (currently unused) |
Value
an object of class summary.demixr_fit: a list holding the
per-component weight/location/scale table together with the family,
sample size, log-likelihood, AIC, BIC, and convergence code. Has a
print method.
Examples
set.seed(1)
x <- c(rnorm(150, 0, 1), rnorm(50, 4, 1))
fit <- fit_norm2(x, n_runs = 1, NP = 20, itermax = 200, quiet = 0)
summary(fit)