mice fills missing values by imputing each variable from the others
Multivariate Imputation by Chained Equations
At a glance
- What is it?
- mice is the R package behind Fully Conditional Specification, the method that replaces missing cells in multivariate data with multiple plausible values and then pools the resulting estimates. It ships on CRAN under GPL-2.0, and the blocks and where arguments are what separate version 3 from the classic one-variable-at-a-time loop.
- Who is it for?
- Adopt mice when your missingness is substantial and your estimates need to carry the uncertainty it creates, and when you are willing to specify imputation models per variable and inspect the diagnostics before trusting a pooled result. Skip it for small amounts of missingness where complete-case analysis costs you little, and for data whose missingness mechanism you cannot justify, since the package does not make that assumption for you.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 108 days ago.
- What is it written in?
- Mainly R, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
mice imputes each variable with its own conditional model
mice implements Fully Conditional Specification, and the name of the method is the whole design. Every incomplete variable is imputed by a separate model, fitted to the variables that are observed, and then the models are chained: each imputation round updates one variable at a time, so information from a newly imputed value can feed the model for the next variable. The result is not a single filled-in table but a set of completed datasets, in this case m of them, each a plausible version of what the original data might have looked like. The data types the package claims to handle are broad: continuous, binary, unordered categorical and ordered categorical variables, plus continuous two-level data. Where a variable is a deterministic function of another, passive imputation keeps the relationship consistent across every completed dataset. The theory behind the method is documented in the Journal of Statistical Software paper by van Buuren and Groothuis-Oudshoorn and in the second edition of Flexible Imputation of Missing Data, both linked from the README.
Blocks collapse the one variable per step assumption
In the classic algorithm each block of the chain is equivalent to one variable, which is the default behaviour and the reason the method is called chained equations. The blocks argument removes that restriction. A block is simply a collection of variables, and allowing a block to hold several variables lets a single imputation model inside that block see them jointly. The README is direct about why this matters, describing the feature as a bridge between two seemingly disparate approaches, joint modeling and fully conditional specification, inside one framework. This is the difference between version 3 and the earlier package, and it is the difference between a tool you have to fight to use for correlated variables and one that can express a multivariate model for a group of them while keeping the chained loop for everything else. The cost is that the argument does not let you mix methods arbitrarily, since the blocks argument allows mixing univariate imputation methods with multivariate ones, but the set of methods has to be one the package ships.
The where argument makes the set of imputed cells explicit
Before version 3, imputation was decided by which cells were empty, and there was no way to say that a particular gap should be left alone or filled under a different rule. The where argument is a logical matrix the same size as the data that specifies which cells should be imputed, and it opens up analytic options that the default pattern-following approach could not express. In practice this matters for the kind of question that separates imputation from data manipulation, for instance when a structural absence in one variable should stay missing while a random gap in another is filled. The argument also interacts with the rest of the pipeline, since the model for each variable is still fitted to observed data and the imputations are still pooled, but the set of cells that get touched is now a parameter of the call rather than a side effect of the data layout. The README lists it as one of the defining features of the 3.0 rewrite, alongside blocks and the multivariate test functions.
Installing from CRAN and running the nhanes example end to end
The package is on CRAN, and the installation step is the standard R one:
install.packages("mice")The README also documents pulling the latest version straight from the repository, which needs devtools:
install.packages("devtools")
devtools::install_github(repo = "amices/mice")A first run looks at the data before touching it. The nhanes dataset ships with the package, and md.pattern prints where the gaps are:
library(mice, warn.conflicts = FALSE)
md.pattern(nhanes)Then the imputation itself, with two imputations and two iterations in the minimal example:
imp <- mice(nhanes, maxit = 2, m = 2, seed = 1)The object imp holds the completed datasets. You then fit your actual model to each one and pool the results, which is the step most people skip and the step that makes the method worth the effort:
fit <- with(imp, lm(chl ~ age + bmi))
summary(pool(fit))The complete-data model is fitted to each imputed dataset and the results are combined into estimates that account for the missing data.
pool() turns separate fits into one estimate with proper error bars
The with() and pool() pair is the analytical heart of the package, and it is where multiple imputation differs from simply filling in blanks. with(imp, lm(chl ~ age + bmi)) fits the complete-data model once per imputed dataset, and pool() combines those fits into a single set of coefficients, standard errors, test statistics and degrees of freedom. The pooled output in the README shows exactly what you get: an estimate for each term, a standard error, a statistic, a df value and a p value for the intercept, age and bmi. Those standard errors are wider than they would be on a single filled-in table, because the spread between the imputations is folded back into the uncertainty. The df column matters just as much, and the numbers in the minimal example are small because the example deliberately runs with m = 2 and maxit = 2. Treat that configuration as a smoke test that the plumbing works, not as an analysis setting, since the number of imputations and the number of iterations are arguments you have to choose deliberately rather than copy from a README block.
Diagnostic plots are how you check whether imputations are plausible
The stated goal of the imputations is plausibility, meaning values that could have been observed if they had not been missing, and the package ships diagnostic plotting to inspect that rather than asking you to take it on faith. md.pattern gives the layout of missingness, a table and a graph where blue marks observed cells and red marks missing ones. In the nhanes output the pattern is far from uniform: age is complete across the sample while chl is missing in 27 of 25 rows, and bmi and hyp each have their own gaps. That asymmetry is exactly the kind of information a reader needs before trusting an imputation, because it tells you which variables will carry the most imputed information and therefore which estimates will move most. The per-imputation diagnostic plots the other way: a stripplot of one variable across the imputed datasets shows whether the imputed values sit inside the observed distribution or drift away from it. The README notes that many such diagnostic plots are implemented.
Joint modelling and complete-case analysis are the two paths not taken
If imputation is not for you, the honest alternatives are on either side of it. Complete-case analysis simply drops every row with a gap, which throws away observed values and, on data like nhanes where chl alone is missing in 27 rows, can shrink the sample sharply while quietly changing the population you are estimating. Joint modelling, the other side, fits a single multivariate model to the whole data set at once instead of building it variable by variable, and the blocks feature exists precisely because the two traditions had been kept apart. The trade-off between them is what FCS gives up and joint modelling gains. FCS is easier to specify, handles mixed data types in one pipeline, and lets you impose different models per variable, but it relies on a set of conditional models that each impute a variable given the others, and it cannot represent relationships that only appear jointly. Nothing in the README describes a diagnostic that tells you the conditional models are wrong, so plausibility has to be checked by looking at the imputations.
A GPL-2.0 package on CRAN with a long release history
mice is distributed under GPL-2.0, with the licence file in the repository root, and it is distributed through CRAN rather than only from source, which is the practical point for anyone considering it in an analysis workflow: the package passes CRAN checks and is installed the same way as any other R library. The release history is steady, with v3.17.0 tagged in November 2024, v3.18.0 in May 2025 and v3.19.0 in December 2025, and the last push to the repository was on 2026-07-07 with the repository not archived. The README badge points at a GitHub version of 3.19.10, which indicates that work continues on the branch between tagged releases. The package is not a small script. The repository root holds R/ for the package code, src/ for compiled sources, tests/, vignettes/, man/ pages, a revdep/ directory for reverse dependency checks and a pkgdown/ site configuration, and the README itself is generated from README.Rmd. That structure signals a package with a review process around it, and with the GPL-2.0 terms applying to any redistribution you make of the package itself.
Editorial conclusion
Adopt mice when your missingness is substantial and your estimates need to carry the uncertainty it creates, and when you are willing to specify imputation models per variable and inspect the diagnostics before trusting a pooled result. Skip it for small amounts of missingness where complete-case analysis costs you little, and for data whose missingness mechanism you cannot justify, since the package does not make that assumption for you. Before starting, read the pooled output of summary(pool(fit)) on the nhanes example and check the degrees of freedom, which in the minimal example are small because it runs with m = 2 and maxit = 2.
Frequently asked questions
What is the mice package used for?
mice is an R package that handles missing data in multivariate datasets. It creates multiple imputations using Fully Conditional Specification, where each incomplete variable is imputed by a separate model, and it can impute mixes of continuous, binary, unordered categorical and ordered categorical data.
How do I install mice and run a first imputation?
Install it from CRAN with `install.packages("mice")`, or from GitHub with `devtools::install_github(repo = "amices/mice")`. Then load the package and call `mice(nhanes, maxit = 2, m = 2, seed = 1)` on the bundled nhanes data to produce the completed datasets.
What is the difference between the blocks and where arguments?
The blocks argument collects variables into a group so that one block can use a multivariate imputation method, which bridges joint modeling and fully conditional specification. The where argument is a logical matrix the same size as the data that specifies which cells should be imputed.
How do I analyse data after imputing it?
Fit your model to each imputed dataset with `with(imp, lm(chl ~ age + bmi))` and then combine the fits with `summary(pool(fit))`. The pooled output reports an estimate, standard error, statistic, degrees of freedom and p value per term, with uncertainty that accounts for the missing data.
How can I check the quality of the imputations?
Use `md.pattern(nhanes)` to see where the missing values sit and `stripplot(imp, chl, pch = 19, xlab = "Imputation number")` to compare the imputed values against the observed distribution for a variable. The README states that many diagnostic plots are implemented for inspecting imputation quality.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/amices-mice)Was this useful?