The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Getting started with missknn

Overview

missknn imputes missing values in tabular data with a masked k-nearest-neighbor engine: distances are computed only on jointly observed variables, the compute-heavy steps (distance, neighbor ranking, aggregation) run in C++, and each column’s neighborhood size and estimator are chosen automatically from a small internal holdout evaluation rather than fixed globally.

library(missknn)

Single imputation

set.seed(1)
x <- data.frame(
  a = c(1, 2, NA, 4, 5),
  b = c(2, NA, 3, 4, 6),
  g = factor(c("x", "x", "y", NA, "y"))
)

imp <- missknn(x, k = 2, m = 1)
missknn::complete(imp)
#>          a        b      g
#>      <num>    <num> <fctr>
#> 1: 1.00000 2.000000      x
#> 2: 2.00000 2.336285      x
#> 3: 2.74969 3.000000      y
#> 4: 4.00000 4.000000      y
#> 5: 5.00000 6.000000      y

missknn() detects numeric and categorical (factor/character/logical) columns automatically, and imputes both from the same masked-distance neighborhood: numeric targets get a distance-weighted mean or a local regression fit (whichever validates better for that column), categorical targets get a distance-weighted majority vote.

A note on complete()

complete() is a common generic name - packages like mimar or tidyr may also define one. If another attached package’s complete() shadows missknn’s, call it explicitly:

missknn::complete(imp)

Multiple imputation

Setting m > 1 draws m completed datasets by sampling (rather than averaging) from each receiver’s nearest donors, using the same distance model throughout:

imp_mi <- missknn(x, k = 2, m = 5, seed = 1)
length(missknn::complete(imp_mi))
#> [1] 5

Per-column adaptive tuning

Rather than using one fixed k for every column, missknn() runs a small internal holdout evaluation per column to choose:

This is inspected via the fitted object’s meta:

imp$meta$k_per_col
#> [1] 2 2 2
imp$meta$estimator_per_col
#> [1] "regression" "regression" "regression"
imp$meta$is_global_col
#> [1] FALSE FALSE FALSE

Why this matters for larger data

Naive KNN imputation searches every donor for every missing value: cost grows quadratically with the number of rows. missknn bounds the neighbor-search candidate pool with donor_cap (default 2000), so cost stays close to linear in n even for large datasets, while the per-column global fast path above further skips neighbor search for columns where it wouldn’t help anyway. See vignette companions in inst/benchmark/ for runtime and accuracy comparisons against missForest, missRanger, and VIM::kNN, including a scaling study from n = 1,000 to n = 100,000.

Options at a glance

missknn(
  data,
  k = 5L,                 # default neighbor count (tuned per column)
  m = 1L,                 # 1 = single imputation, >1 = multiple imputation
  scale = TRUE,            # standardize numeric variables before distances
  weights = "distance",    # "distance" (inverse-distance) or "uniform"
  numeric_estimator = "regression", # "regression" or "mean"
  donor_cap = 2000L,       # cap on the neighbor-search candidate pool
  add_indicator = FALSE,   # append missingness indicator columns
  seed = NULL              # reproducible multiple imputation
)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.