impute(imputer = "missknn") works with missknn 1.2.0, which returns the
completed data directly instead of a missknn object; earlier missknn
versions keep working.basetable (>= 1.4.2): the
evaluate() recovery table (basetable::aggregate()), the proportion plot
data (basetable::count() and basetable::merge()), and tabular
pool() (basetable::split()). Pooled terms and metrics now keep their
input order instead of being sorted alphabetically, and the recovery table
is ordered by variable.impute(imputer = "polyreg") failed with "'x' must be an array
of at least two dimensions" when a multiclass factor had exactly one
missing value.pool_panglm() used df.residual() as the complete-data df
whatever covariance the fits carried. For cluster-robust fits
(panglm(..., vcov = "cluster")) that is the classical NT - N - K,
which overstates the Barnard-Rubin df and narrows intervals when the
number of panel individuals G is small. The default is now
G - 1 for cluster-robust fits and df.residual() otherwise, and the
new dfcom argument overrides it. The value used is returned as dfcom.pool_test() with method = "D1" on panglm fits uses the same default
complete-data df when dfcom is NULL.pool_panglm() also warns when the fits differ in covariance type, and
its documentation states that a single-level imputation model is not
valid for within or random-effects analyses.y collided with the internal response name of
the regression-based imputers (norm, pmm, logreg, polyreg,
ranger, rpart, naive_bayes, svm) and was silently dropped from the
imputation model. The internal response is now .mimar_y.New pool_test() for pooled multi-parameter tests after multiple
imputation, e.g. all levels of a factor or a model against a nested one:
D1 (multivariate Wald, Li, Raghunathan and Rubin, 1991, with the Reiter
2007 small-sample df when dfcom is given), D2 (combined Wald or
likelihood-ratio chi-square statistics, Li, Meng, Raghunathan and Rubin,
1991), and D3 (Meng and Rubin, 1992, likelihood ratio for lm and
gaussian/binomial/poisson glm), each with an F reference distribution.
Results match mitml::testModels().
pool() accepts a named pooling scale, transform = "log", "logit",
"cloglog", or "fisherz", so that bounded or skewed quantities (ratios,
probabilities, AUC, C-index, correlations) are pooled where the normal
approximation behind Rubin's rules holds (Marshall et al., 2009). Variances
are given on the original scale and carried over with the delta method;
estimates, standard errors, and intervals are reported on the original
scale. Tidy metric rows (metric, value, imputation) that also carry a
std.error column are now pooled with Rubin's rules instead of the robust
summary, and honour transform. Intervals are now ordered correctly when
a function transform has a decreasing inverse.
pool() and pool_survmat() gain a dfcom argument (complete-data
degrees of freedom). When supplied, Rubin pooling uses the Barnard and
Rubin (1999) small-sample degrees of freedom, as the model poolers
(pool_lm(), pool_glm(), ...) already did. Without it, the classic Rubin
(1987) degrees of freedom are kept; they assume a normal complete-data
reference and can be far too large in small samples. Results match
mice::pool() with the same dfcom.
pool(rule = "mean") now honours conf.level; it previously always
returned a 95% interval. Its documentation now states that it uses only the
between-imputation variance.
Migrated the internal .as_dt()/.rbind_or_empty() helpers (the shared
row-binding/coercion choke point behind every public return object) from
data.table to basetable. Public return objects (describe(),
impute(), complete(), evaluate(), pool(), imputer_registry())
are now basetables instead of data.tables. typeconflict = "coerce"
is used at the one row-bind site that legitimately mixes column types
across inputs (plot-data assembly). Also fixed a latent infinite-recursion
bug this surfaced in print.mimar_imputers(): basetable::as_basetable()
is a no-op on anything already carrying class "basetable", so calling
it on a describe("imputers") result (tagged "mimar_imputers" on top of
"basetable") returned the object unchanged instead of a clean table,
causing print() to recurse into itself. .as_dt() now always strips to
a plain data.frame first.
The gbm imputer is now fastgbm: imputer = "gbm" is replaced by
imputer = "fastgbm", backed by the fastgbm package (compiled
gradient boosting, native regression/binary/multiclass objective
inference) instead of gbm. gbm dropped from Imports in favor of
fastgbm. Hyperparameters passed through imputer()/... change
accordingly (ntrees, learning_rate, max_depth in place of
n.trees, shrinkage, interaction.depth).
Added nelsonaalen() and ipcw(), preprocessing helpers for imputation
with time-to-event data. nelsonaalen() returns the Nelson-Aalen
cumulative hazard at each subject's time, the predictor to use in place of
the raw survival time when imputing other covariates (White and Royston,
2009); it matches mice::nelsonaalen() with no auxiliary variables and,
when aux is supplied, estimates the cumulative hazard within strata
(categorical aux) or from a Cox model (method = "breslow").
ipcw() returns subject-level inverse-probability-of-censoring weights
Delta_i / G(T_i-) from a Kaplan-Meier censoring model, with aux support
for covariate-dependent censoring (stratified Kaplan-Meier or method = "cox"), plus type = "all", stabilized, and truncate options. Both
accept the time and status columns either as strings or as unquoted
symbols. The Cox paths use survival (already in Suggests).
densemlp imputer now runs on densemlp's native
C++/RcppArmadillo dense MLP (no torch/libtorch dependency, faster to
fit). imputer = "densemlp" fits/predicts through the standard chained
loop as before, but task detection is finer-grained: "regression",
"binary", and "multiclass" are distinguished natively, matching
mimar's own per-variable task detection exactly, instead of the previous
single "classification".pool_panglm(), pooling a list of panglm panel-data model fits
(one per completed data set) across imputations using Rubin's rules,
following the design of the existing pool_glm()/pool_lm() (printed
coefficient table mirroring summary.glm(), t value/z value labelled
by family, Barnard-Rubin corrected degrees of freedom from
df.residual() when the panglm estimator provides one - model = "pooling"/"within" do; model = "random" does not compute a full
likelihood and falls back to a normal reference distribution). Warns
(does not error) if the fits being pooled disagree on panglm's
model/effect/family settings. panglm added to Suggests for the
example/tests. devtools::test(): all pass, including a new
test-pool-panglm case. R CMD check --as-cran: Status OK, 0 errors/0
warnings.pool_coxph(), pool_glm(), pool_lm(), pool_survreg(), and
pool_clogit(), convenience helpers that pool a list of fitted models
(one per completed data set) using Rubin's rules and print a coefficient
table formatted like the corresponding base-R summary() output
(summary.coxph(), summary.glm(), summary.lm(), summary.survreg();
pool_clogit() matches pool_coxph() since clogit() fits a stratified
Cox model internally). Degrees of freedom use the Barnard and Rubin (1999)
correction rather than the classic Rubin (1987) formula, which can diverge
to implausibly large values when between-imputation variance is small
relative to within-imputation variance; all five were cross-validated
against mice::pool() to numerical precision on matched examples.densemlp imputer, wrapping the densemlp package's dense
multilayer perceptron as a standard fit/predict learner inside the chained
imputation loop (numeric targets predict a point estimate, categorical
targets draw from predicted class probabilities).missknn imputer, wrapping the missknn package's whole-table
masked k-nearest-neighbor engine. Because missknn imputes all variables
jointly in one pass rather than per-variable, selecting it bypasses the
chained-equations loop entirely as a distinct single-shot strategy.progress argument to impute(), showing an elapsed/ETA progress
bar over completed datasets via functionals::fmap(pb = TRUE). Defaults to
TRUE in interactive sessions when verbose = FALSE, and has no effect
when imputer = "missknn".tibble dependency package-wide. All tabular results
previously returned as tibbles (describe(), impute(), complete(),
evaluate(), pool(), imputer_registry(), and friends) are now
data.tables instead. Internal row-binding of trace/diagnostic/pooling
data frames also moved from base do.call(rbind, ...) to
data.table::rbindlist(), the shared backend behind .rbind_or_empty().
The engine internals (chained-equations loop, amputation) still operate on
plain data.frames to keep base-R subsetting semantics intact; only the
user-facing return objects changed class.superlearner and sl imputers. These construct a Super
Learner-style ensemble by cross-validating candidate imputers on observed
cells, assigning non-negative loss-based weights, and combining predictions
inside the existing chained-imputation loop.library, folds, and metalearner hyperparameters for
superlearner.First public release candidate.
ncore to impute() for completed-dataset-level parallel imputation
through functionals::fmap().mimar_imputation diagnostics for
convergence screening.mimar a distinct visual
identity while retaining the existing plot themes.funcml dependency.