← All Posts
Deep Learning · Data Preparation and Preprocessing · Handling Missing Data

Deletion: Listwise and Pairwise

Deletion analyzes the values already present without filling gaps. Its consequences depend on which columns the analysis needs, which rows survive, and what quantity you want to estimate.

Two common forms are listwise deletion, which keeps rows complete on all required columns, and pairwise deletion, which uses a separate available subset for each pair of columns. Neither changes a missing value into an observed one. Both can change which cases contribute to the result.

Listwise deletion starts with the required columns

Suppose an analysis requires A, B, and C. A row survives only if all three are observed. In the constructed table below, rows 1 and 3 survive. If the analysis requires only A and B, row 5 can also be used: its missing C is irrelevant to that particular calculation.

RowABC
1 · keep110100
22—200
3 · keep330300
4—40400
5550—
66——
A dash marks a missing value. Complete for A, B, and C: rows 1 and 3. Complete for A and B only: rows 1, 3, and 5. Define the analysis columns before dropping rows; an unused column should not silently determine eligibility.

Dropping rows also changes alignment. Keep row IDs or a shared Boolean mask so that features, targets, sample weights, and group IDs all retain the same examples in the same order.

Small per-column missing rates can remove many rows

For a planning calculation, assume each of $d$ required columns is independently missing with probability $p$. A given column is present with probability $1-p$. A row survives only when all $d$ are present, so multiply those probabilities:

$$P(\text{complete row})=(1-p)^d.$$

With a 5% missing rate in each of 20 independently missing columns, the retained fraction is $0.95^{20}\approx0.3585$. That means roughly 359 survivors per 1,000 rows on average, even though no individual column has many gaps.

The independence assumption matters. If the same rows are missing all 20 columns, the retention pattern is very different. Measure actual row completeness and its breakdown by class, group, and date; do not infer it from a list of column percentages alone.

Validity depends on the quantity being estimated

Under MCAR, complete cases form a random subset with respect to the relevant data, which supports many ordinary complete-case estimates while sacrificing information. It is a useful sufficient condition, not a universal necessary condition for every analysis.

For example, consider a correctly specified regression with fully observed predictors and missing outcomes. If an outcome’s chance of being observed depends only on those predictors, the conditional outcome distribution at a fixed predictor value is unchanged by selection. The regression relationship can remain estimable where there is adequate observed support, even though the overall distribution of observed predictors changes.

How a pooled mean can change while a conditional relationship survives

Imagine 100 Basic accounts with mean usage 20 and 100 Pro accounts with mean usage 80. The population mean is 50. Suppose outcome collection depends only on plan and leaves 80 Basic accounts and 20 Pro accounts, with the same within-plan means in this constructed example.

The observed pooled mean becomes $(80\times20+20\times80)/100=32$. The two within-plan means remain 20 and 80. Estimating the overall mean and estimating the relationship conditional on plan are different tasks. Validity for one does not establish validity for the other.

Real regression conclusions additionally depend on the model, the observation mechanism, and sufficient data across the relevant predictor values. Van Buuren’s discussion of complete-case regression gives the conditions and exceptions in more detail.

If selection still depends on the unseen outcome after conditioning on the predictors, that reasoning no longer applies. A label such as MAR or MNAR should be connected to the actual variables and estimand; it is not a blanket approval or rejection of deletion.

Pairwise deletion uses a different subset for each relationship

In the first table, the A–B correlation uses rows 1, 3, and 5; A–C uses rows 1, 2, and 3; B–C uses rows 1, 3, and 4. Each pair has three available cases, but they are different cases.

This can be useful for an exploratory table when you also report each pair’s sample size. It does not produce a completed feature matrix for a model. It can also produce a collection of correlations that could not all arise from one common set of complete observations.

A six-row example of an impossible correlation matrix

Use this separate constructed dataset. Each pair is observed in exactly two rows:

Row   A   B   C
1     1   1   —
2     2   2   —
3     1   —   1
4     2   —   2
5     —   1   2
6     —   2   1

The available A–B pairs increase together, giving correlation +1. So do A–C. The B–C pairs move in opposite directions, giving correlation −1. These perfect relationships cannot all hold for the same three standardized variables: if A equals B and A equals C, then B must equal C too.

A valid correlation matrix must be positive semidefinite: every linear combination of the standardized variables has nonnegative variance. Combining the three pairwise results would instead imply

$$\operatorname{Var}(A-B-C)=3-2(1)-2(1)+2(-1)=-3.$$

Here A, B, and C denote hypothetical centered, unit-variance variables with those correlations. The initial 3 adds their three variances; the remaining terms are their signed covariance contributions. A negative variance is impossible. The two-row pairs make the contradiction easy to see, but the broader problem is that each relationship used a different sample.

For prediction, report who receives a prediction

A service that rejects incomplete inputs needs an explicit fallback or abstention policy. Its accuracy among accepted inputs does not describe all incoming requests.

01200 requests arrive40 are incomplete and receive no prediction.
02160 receive predictions144 correct, 16 incorrect: accuracy among scored requests is 90%.
03Report the missing 40 tooCoverage is 160 / 200 = 80%. Correct predictions cover 144 / 200 = 72% of all requests.
Keep accuracy and coverage separate. These counts are constructed. The last percentage counts successful predictions across all requests; it is not the same metric as accuracy conditional on making a prediction.

If production must score incomplete inputs, train and evaluate a procedure that handles those inputs. Appending a serving-time imputer to a model assessed only on complete cases does not establish its performance on imputed inputs. Compare a coherent imputation pipeline, a model that handles missing features, or an explicit fallback using representative held-out data.

C++: return retained row indices

The implementation checks only the requested columns. Returning indices makes it possible to apply the same selection to every aligned array.

Compile the complete-case index filter
#include <cmath>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <vector>

std::vector<std::size_t> completeRows(
    const std::vector<std::vector<double>>& X,
    const std::vector<std::size_t>& columns) {
    std::vector<std::size_t> kept;
    for (std::size_t i = 0; i < X.size(); ++i) {
        bool complete = true;
        for (std::size_t j : columns) {
            if (j >= X[i].size())
                throw std::invalid_argument("column outside row");
            if (std::isnan(X[i][j])) complete = false;
        }
        if (complete) kept.push_back(i);
    }
    return kept;
}

int main() {
    const double NA = std::numeric_limits<double>::quiet_NaN();
    std::vector<std::vector<double>> X = {
        {1, 10, 100}, {2, NA, 200}, {3, 30, 300},
        {NA, 40, 400}, {5, 50, NA}, {6, NA, NA}
    };
    std::vector<int> labels = {0, 1, 1, 0, 1, 0};
    auto kept = completeRows(X, {0, 1, 2});
    for (std::size_t i : kept)
        std::cout << "row " << i + 1 << ": label " << labels[i] << "\n";
    // Reuse these same indices for X, labels, weights, and row IDs.
}
row 1: label 0
row 3: label 1

Before adopting deletion, record which columns require completeness, how many cases are lost, what changes in the retained population, and what happens to incomplete inputs at deployment. Those checks make the decision interpretable without turning a convenient data-cleaning operation into an unsupported statistical assumption.

References and further reading