On this page
Cluster analysis – method notes
The decisions behind the cluster analysis module – which bound, refusal, fallback or package argument stands behind each card, and the numbers that validate them, each computed on the example dataset (cafe.csv, its spec beside it) with the data page’s three fixes applied. Sections follow the manual’s.
Requirements
Every k is held below the number of objects, and a Step 2 range’s maximum with it. A k equal to the object count is an all-singleton solution: cluster::silhouette() returns a bare NA there, which takes the whole validity block down with it, and Calinski–Harabasz divides by n − k. So case mode needs k + 1 complete cases and variable mode k + 1 variables – and still two complete cases, since dist() over the transposed matrix needs two rows to see any spread between two variables. The refusal is a toast naming both counts, before anything reaches R.
Validation. On the café’s rating, spend and visits after the change, 192 members are complete, so k = 192 is refused – “Not enough complete cases (192) for 192 clusters” – and k = 191 is the largest the run accepts.
Biclustering needs two complete cases, as many as the biclusters asked for, and under FABIA no more biclusters than variables. The auto-k algorithms carry no k to check the row count against, and a one-row matrix reaches R and dies there with a raw package error, so two complete cases is the floor for every algorithm; fabia() hard-errors with “Too many biclusters. Stopped.” once the count passes min(nrow, ncol), and the columns are always the binding side here, so FABIA’s k is capped at the variable count before the run – where Cheng & Church and BiMax simply return fewer biclusters than asked for and need no cap.
Constant variables are dropped before the run, and listed. scale() maps a constant column to NaN, which kmeans() rejects and dist() silently drops, so a variable constant across the complete cases would either abort the run or vanish from it without a trace; the module removes it first, prints it as Excluded (no variance), and refuses the run when fewer than two variables are left.
Number fields are read back repaired, never raw. An empty number input parses to NaN, and every comparison against NaN is false, so an unguarded value slips past every range check and interpolates into the R source as the literal NaN; a value the browser accepted but never enforced reaches R as an out-of-range argument – probs = 1.5, iter.max = 0, p = 0. Every numeric setting is therefore read as its value clamped to the min and max its markup declares, or as its default when the field is empty – Step 3’s two k fields excepted, which are read as typed and refused with a toast when empty or below their minimum; and a Step 2 range is kept usable on its own – a maximum repaired down to the minimum is raised to one above it, since the comparison needs a range.
Step 1: Method & settings
Standardization is forced on in variable mode and off under Gower, and the user’s own choice is kept meanwhile. The squared Euclidean distance between two z-scored columns is , so standardizing the columns is exactly what makes a variable-mode distance a correlation – an unstandardized variable-mode run would measure something else under the same label, so the box is ticked and locked. Gower divides each numeric variable’s difference by that variable’s own range, and the ratio is unchanged by any linear rescaling of the column, so a prior z-scoring would leave every coefficient as it was while the card reported a standardization that did nothing; the box is unticked and locked instead. The user’s own answer is remembered while either lock holds and restored when it lifts.
Validation. On the six café items in variable mode, the Ward tree under Euclidean distance and the tree under 1 − r cut at two give the same partition – slow against the other five – and the Euclidean tree’s first merge, taste with fresh at height 13.95, is , the 1 − r tree’s own first height.
The metric select is hidden under k-means in case mode, pinned to Euclidean in variable mode, and gated by disabling rather than hiding. k-means minimises squared Euclidean distance – the mean is the point that does – so it cannot honour another metric. In case mode the select is hidden without being reset, so a metric picked for k-medoids or hierarchical survives a detour through k-means; in variable mode it stays on screen because there the metric is what “similar variables” means, and hiding it would put the two correlation entries out of reach – the entries k-means cannot use are disabled, never hidden, since a hidden option stays reachable by keyboard and typeahead and the select could then hold a value the run silently overrides. Whatever the select holds, the run resolves the metric it can honour – Euclidean under k-means, and Euclidean when Gower is left over in variable mode, where averaging per-variable scores has no reading once the columns are the objects – so a leftover never grades a solution under a geometry it never optimised. Pinning loses nothing: on standardized variables Euclidean k-means already reproduces the 1 − r clustering, by the identity above.
Ward’s is flagged on a non-Euclidean metric, and each tree is built on the scale its linkage assumes. Centroid and median linkage are Lance–Williams recurrences over squared Euclidean distances and ward.D2 squares its input internally, while 1 − r and Gower’s 1 − s are already squared distances – both similarities are positive semi-definite, so their complements embed as squared Euclidean ones. Metric and linkage together therefore decide what hclust() is handed: centroid and median on a plain dist() get d² and their heights are square-rooted back, ward.D2 on a correlation or Gower dissimilarity gets √d and its heights are squared back, and every other pairing is passed as it is – so every branch returns heights on the dissimilarity’s own scale, which is what the dendrogram axis and the cophenetic correlation read against. The Ward warning fires only on a non-Euclidean metric, Minkowski at p = 2 counting as Euclidean; the centroid and median warning fires on any metric, since hclust defines both for squared Euclidean distances and produces non-monotone merge heights when fed a plain dist() object. An inversion is a real diagnostic, so the heights are drawn as they are and counted in a note on the plot rather than smoothed away.
Validation. On the café’s three standardized variables, centroid linkage produces 9 inversions among its 191 merges and the note appears; Ward’s last three merges sit at 12.48, 12.77 and 16.21 on the Euclidean scale.
Gower reads each column’s class, and the app produces three of daisy’s six sub-types. daisy() decides how a column is compared from its class: the module hands an ordinal variable over as an ordered factor with its levels sorted numerically – ordered() sorts them as text otherwise, putting 10 before 2 – which is Podani’s rank treatment, a categorical variable as a plain factor, and a numeric column as it is; the sub-type codes are read back from the dissimilarity’s Types attribute and printed as the Gower variable types row, since nothing else on the card shows how a variable was scored. daisy’s asymmetric-binary, symmetric-binary and log-ratio codes need a type = argument the module never passes, so the row can only ever read interval, nominal or ordinal – a two-level categorical variable is nominal and a 0/1 numeric one interval. Podani’s paper is cited only when an ordinal variable was present, since a run carrying none never used his treatment.
Validation. On rating, spend, visits, branch and recommend the row reads interval, interval, interval, nominal, nominal, and the coefficient between the first two members is 0.257 – the mean of 0.111, 0.079, 0.093, 0 and 1.
Under Gower the centroid family is withheld and Davies–Bouldin switches to medoids. The sums of squares, variance explained, Calinski–Harabasz, Hartigan, Hopkins, Duda–Hart, the gap statistic and the elbow plot are centroid quantities over a numeric matrix: a mixed-type frame has no mean to take, no bounding box for Hopkins’ uniform probe, no Je for Duda–Hart, and no principal-component box for the gap’s reference. Reporting them from a Euclidean matrix the run never clustered on would grade the solution under another geometry, so they are left off with a note on the card. Davies–Bouldin is recomputed from cluster medoids on the dissimilarity – the index’s own alternative parameterisation, not a substitute statistic – while silhouette, Dunn, the cophenetic correlation, bootstrap stability and the consensus partition read the dissimilarity directly and are unchanged. The biplot rests on prcomp(), which needs a numeric matrix and one arrow per clustering variable, so it is withheld with a note as well; k-means is withdrawn because it needs centroids; cluster profiles and medoids print a modal level where a mean is undefined, and the variable contribution table’s F and η² compare means, so a categorical variable’s row leaves both empty and a note says so.
K-means non-convergence is read off ifault and the iteration count. kmeans() reports ifault 2 – not converged in iter.max – and 4 – quick-transfer steps exceeded – for Hartigan–Wong only, and the other three variants report nothing, so the run also reads an iteration count at or above the limit as a failure for every variant; the warning names the count reached and the two remedies, a higher limit or more starts. The random starts run under the reproducibility seed, so the same data and settings pick the same starts and the best of them is the same solution.
Validation. On the café’s three standardized variables, k = 3 converges in 2 iterations from the best of 25 starts and no warning is printed.
The plaid background is a grand mean plus row and column effects, and a layer is kept only when it beats three shuffles. biclust documents BCPlaid’s background = TRUE as a background layer “constant for all rows and columns”, but with background.layer left NA it fits that layer with the layer model itself, y ~ m + a + b, over the whole matrix – 1 + (n − 1) + (p − 1) degrees of freedom – so what is removed before the first bicluster is a grand mean plus one effect per case and one per variable, not a constant; with FALSE no background is fitted and the first layer is searched on the values as they stand. Each candidate layer’s sum of squares is compared with the layers fitted on shuffle = 3 permuted copies of the matrix and kept only when it exceeds all three, which is how the model stops on its own. The release rule keeps a case in a layer only while the layer’s residual mean square for that case is below (1 − release) times its total mean square across the layer’s variables, and the same for a variable across the layer’s cases, so a higher release prunes harder.
Validation. On the six café items Plaid returns no layer, standardized or not: no candidate beats its shuffles, since the items’ structure is two factors touching every member rather than blocks.
BiMax binarizes each column at its own quantile. biclust’s binarize() takes one threshold for the whole matrix, which means something different for every variable whenever the run is not standardized; the run instead cuts each column at the chosen quantile of its own values – above it 1, at or below it 0 – and hands the binary matrix to BCBimax() with the two size minimums.
Validation. On the six café items cut at their medians, k = 3 returns 36 members × {value, friendly}, 11 × {quick, slow} and 36 × {taste, value}.
Cheng & Church’s δ is a fraction of the matrix’s own residue, and found rows are masked, not deleted. biclust takes delta as an absolute mean-squared-residue ceiling, which says nothing without the matrix’s scale, so the user’s value multiplies the whole matrix’s residue. BCCC() drops the rand argument, and biclust defaults it to FALSE – which deletes each found bicluster’s rows from the matrix instead of masking them with random values as Cheng and Church prescribe – so the run calls the package’s internal routine with rand = TRUE. alpha is the multiple-node-deletion factor: rows and columns whose mean residue exceeds α × the block’s are removed together before the one-at-a-time deletion and the node addition run.
Validation. The standardized six-item matrix has a mean squared residue of 0.735, so δ = 0.2 is a ceiling of 0.147; the first bicluster returned is 42 members on the five items other than slow, at 0.141.
FABIA’s membership is decided by the threshold, not the sparseness priors. FABIA’s sparsity is soft – nothing in its loadings or factors is ever exactly zero – so membership comes from extractBic(fit, thresZ)'s thresholded row and column indices, and extractBic derives the loading threshold as √mom / thresZ, which is why raising the threshold admits more cases and fewer variables. A bicluster left with no case or no variable is dropped, which is how a too-low threshold returns nothing at all. spl and spz shape the fit and cyc its iterations; FABIA’s banner and per-cycle messages are muffled so the console shows only what the run itself prints.
Spectral’s counts are bounded by the matrix, and its spread threshold is a fraction of the matrix’s own. BCSpectral() drops n_clusters, and without it biclust runs an auto-search whose window collapses on a narrow matrix and errors with “missing value where TRUE/FALSE needed”, so the run calls the package’s internal routine with the count set. numberOfEigenvalues is clamped to min(nrow, ncol) in R as well as in the panel, since the widget’s maximum is only as fresh as the last selection; the group count is capped in the panel at the smallest of min(nCols, nRows) − 1 – both axes are grouped through Hartigan–Wong, which demands strictly fewer centres than points – nCols − minc and nRows − minr, because g groups leave a widest group of m − g + 1 columns and a bicluster is kept only when it is wider than minc, so every g above m − minc returns nothing however permissive the spread threshold. biclust’s withinVar is a mean row-to-centroid distance on the input scale, not a variance, so the user’s fraction multiplies the whole matrix’s mean row-to-centroid distance; a pairing is kept when it has more rows than minr, more columns than minc and a spread below the threshold. Log normalization shifts the matrix so its minimum is 1 before taking logs and removing the row and column means; IRRC and bistochastization shift it non-negative, and under both the first singular vector carries the background and is dropped, so a request for one singular vector is raised to two with a warning.
Step 2: Determine optimal k
Cluster tendency is tested in case mode on a numeric matrix alone, and in Euclidean geometry whatever the metric. Hopkins probes the bounding box of the objects being clustered and Duda–Hart’s reference distribution is a function of their dimension, so on the transposed variable-mode matrix both would describe the case count rather than the variables; a mixed-type frame has neither a bounding box nor a Je, so under Gower neither runs. Hopkins draws one probe per ten objects – at least two, at most n − 1 – uniformly over each variable’s range on the analysis matrix, and as many real objects, under the reproducibility seed, and reports over Euclidean nearest-neighbour distances – the orientation in which 0.5 is random and 1 clustered. Duda–Hart splits the data with the selected algorithm at k = 2, takes Je(2)/Je(1) as that split’s Euclidean within-cluster sum of squares over the total, and tests it one-sided against Duda and Hart’s normal approximation – mean , variance for n objects on p variables – at the significance level in Settings.
Validation. On the café’s three standardized variables Hopkins is 0.811 from 19 probes, and the best two-cluster k-means split leaves 410.51 of 573 units of variation – a Duda–Hart ratio of 0.716, p = .078.
The gap statistic is computed on the run’s own dissimilarity, and k is chosen by Tibshirani, Walther and Hastie’s own rule. cluster::clusGap measures W(k) in Euclidean distance, so the module computes the gap itself: W(k) pools each cluster’s sum of squared within-cluster dissimilarities divided by its size, over whatever dissimilarity the run clusters on, and each of B = 100 reference samples is drawn uniformly over the box of the data’s principal components – the paper’s second reference, which shapes the null to the data’s own spread and orientation – and clustered with the same algorithm, all under the reproducibility seed; the standard error is . k is picked by maxSE(method = "Tibs2001SEmax") – the smallest k with Gap(k) ≥ Gap(k + 1) − s(k + 1), the paper’s rule – rather than cluster’s default firstSEmax, and the rule runs over k = 1 to the range’s maximum whatever its minimum, so it can return 1, or a k below the range; the table’s mark and the plot’s highlight follow the rule, not the column’s maximum. A uniform box is no structureless null for a correlation between profiles, so under 1 − r and 1 − |r| a note says so; under Gower there is no box, and the gap is withheld.
Validation. On the café’s three standardized variables under k-means the gap stays between 0.976 and 1.032 from k = 2 to 10 and the rule returns k = 1, so the card reports that the gap statistic favours no cluster structure while the silhouette suggests 3.
The centroid indices are Euclidean whatever the metric; the separation indices read the run’s own dissimilarity. Within SS, variance explained, Calinski–Harabasz and Hartigan are sums of squares around cluster means, which have no accepted non-Euclidean form, so under another metric they are computed from centroids on the analysis matrix and a note under the table says the table mixes two geometries; under Gower there is no mean to take, and they are left out – Calinski–Harabasz with its checkbox. The silhouette and Dunn read the dissimilarity matrix the run clustered on, and Davies–Bouldin, which Davies and Bouldin parameterise by the distance, measures both its scatters and its centroid separations in that metric – from medoids under Gower.
Within SS and variance explained carry no best mark, and Hartigan’s index is read against 10. Both improve monotonically in k, so a mark on either would point at the largest k tested – the one thing a table for choosing k must not advise. Hartigan’s index is , and Hartigan’s rule of thumb reads a value above 10 as a reason to add a cluster; it needs the next k, so the range’s last row reads N/A.
Validation. On the café’s variables Hartigan is 50.7 at k = 2 – (410.51 ⁄ 323.67 − 1) × 189 – and stays above 10 through k = 9.
The silhouette suggestion is the plain maximum, and a caveat guards the range. Suggested k (silhouette) is the k with the highest average silhouette among those where it is defined, 2 ≤ k < n, falling back to the range’s minimum when none is; the best of a range says nothing about whether the range holds structure, so when no k reaches 0.25 – Kaufman and Rousseeuw’s floor for any substantial structure – a caveat under the suggestions names the best score.
The suggested bicluster count is the most stable k, else the variance-explained elbow, and a flat sweep has none. With stability measured, the suggestion is the k with the highest mean bootstrap Jaccard. Otherwise it is the last k before the gain in variance explained falls below half the gain before it – but a ratio alone fires on noise: BiMax on the hatch fixture gains 0.45 percentage points across k = 2–8 and its first sign flip reads as an elbow, where Cheng & Church over the same range gains 37. So the rule applies only once the curve has risen at least 5 points above its first value, the smallest k tested is suggested otherwise, and the card names the rule it used; when stability was asked for and scored no k, a warning names the fallback.
Validation. BiMax on the six café items over k = 2–6 gains 6.28, 4.72 and 0.93 points, so the gain collapses after k = 4 and 4 is suggested.
Bicluster stability resamples the cases and holds the variables fixed. Each k’s fit – the one the table shows – is scored by Hennig’s (2007) cluster-wise bootstrap Jaccard: rows are drawn with replacement, the algorithm is refitted on the resample, each original bicluster, restricted to the rows the resample contains, is matched to its best counterpart by cell-set Jaccard, and the matches are averaged over the biclusters and the replicates. The variables are the user’s own choice, so they are never resampled. The resampling follows the bootstrap seed in Settings, unseeded by default. Step 3’s per-bicluster Stability column is the same computation on the one fit, a replicate whose refit fails scoring 0.
The F-statistic diagnostics are descriptive only. They come from biclust’s diagnoseColRow, whose null draws cells independently from the whole matrix and so destroys every row and column structure rather than holding the block fixed: any real difference between variables is significant under it, and the biclusters were selected to maximise exactly those effects. The row and column F values are averaged over the biclusters of at least two rows and two columns, the proportions count p-values below the significance level in Settings, and a note on the table and the plot says both are inflated by construction; the 80% line is a reading aid, not a criterion. computeObservedFstat’s parametric p-values test the selected block against itself and are ≈ 0 for the same reason, so only the observed F values are read.
Consensus scoring compares repeated runs in both directions, and only a stochastic algorithm is offered it. At every k the algorithm is refitted as many times as the replications field says, each run under its own seed derived from the bootstrap seed – entropy-seeded when that is unset – and every pair of runs is scored by best-match cell Jaccard in both directions and the two averaged, so a run that found two biclusters cannot score high against one that found ten, and a failed run counts as a zero-scoring pair rather than dropping out. At the default 100 runs that is 4,950 pairs per k. BiMax consumes no random numbers, so its runs are identical and the option is hidden under it.
Step 3: Run full analysis
The silhouette is read against Kaufman and Rousseeuw’s bands, and the cophenetic correlation is always reported for a tree. The average silhouette width is labelled strong from 0.70, reasonable from 0.50, weak from 0.25 and no substantial structure below – Kaufman and Rousseeuw’s reading – and the per-cluster averages of the sizes table come from the same cluster::silhouette() call, so they appear whenever the silhouette is computed, for the validity row or the silhouette plot. The cophenetic correlation grades how faithfully the tree’s merge heights reproduce the input dissimilarities, a property of the tree rather than of any cut, so it has no checkbox, is the same for every k, and is read against the conventional 0.75.
Cluster stability is Hennig’s clusterboot: distinct resampled objects, every object classified back. Silhouette, Calinski–Harabasz and the other indices grade the partition on the sample that produced it and cannot tell a real group from a lucky cut; the bootstrap asks whether the cluster would appear again in another sample (Hennig, 2007). Each replicate draws the objects with replacement and keeps the distinct ones, since a duplicated object would pull a centroid towards itself; reclusters them with the run’s own algorithm and settings; and classifies every object of the full data to its nearest bootstrap representative in the run’s own dissimilarity – the k-means centroids, the PAM medoids, the hierarchical cut’s cluster means, or its medoids under Gower. Each original cluster is then matched to its best counterpart by Jaccard over whole sets, so every replicate whose refit succeeds scores every cluster. Hennig’s bands read the mean: 0.85 highly stable, 0.75 stable, 0.60 a pattern with doubtful membership, below that not trustworthy; a replicate at 0.5 or less counts as dissolved and one at 0.75 or more as recovered. In variable mode the resampled units are the cases the dissimilarity is built from, so every variable is in every replicate and the bootstrap solution is itself the assignment. Replicates follow the bootstrap seed in Settings.
The consensus partition is evidence accumulation, cut by average linkage and renumbered onto the reported solution. The replicates stability draws are reused, so asking for both costs one loop: each replicate’s assignment adds to a co-association count for every pair of objects, divided at the end by the replicates whose fit succeeded (Fred and Jain, 2005). The consensus partition is hclust(as.dist(1 − C), "average") cut at the run’s k; a tree cut numbers its clusters by tree position, so each consensus cluster is renamed after the reported cluster it overlaps most, largest overlap first, which puts agreement on the crosstab’s diagonal. Agreement is the adjusted Rand index of that crosstab, read against Steinley’s (2004) bands – 0.90 excellent, 0.80 good, 0.65 moderate – with a warning below 0.65; PAC is the share of pairs whose co-association lies strictly between 0.1 and 0.9 (Şenbabaoğlu et al., 2014); and each cluster’s mean co-association is Monti et al.'s (2003) cluster consensus, the mean over the distinct pairs inside it, undefined for a singleton.
The sums of squares are Euclidean on the analysis matrix, and the variable contribution F is descriptive. Within and between sums of squares are centroid quantities, so whatever the metric they are taken around the cluster means of the matrix the run clustered – standardized when standardization is on, transposed in variable mode – and under Gower, which has no mean, they are withheld. The contribution table is a one-way ANOVA of each variable on the original scale across the clusters, with df k − 1 and n − k and ; since the partition was chosen to separate these variables, the F is large by construction and no p-value is printed.
Multidimensional scaling reports the fit each method optimises, and is capped at 1,000 objects. Classical scaling is cmdscale(d, k = 2, eig = TRUE), and its goodness-of-fit is GOF[1], taken over the absolute eigenvalues so that a non-Euclidean dissimilarity’s negative eigenvalues count against the two axes rather than being dropped; it has no stress to report. Non-metric scaling is MASS::isoMDS() started from the classical solution, and its stress-1 – returned as a percentage and divided by 100 – is read against Kruskal’s (1964) bands, 0.025 excellent, 0.05 good, 0.1 fair. Both run in compiled code that never polls for an interrupt, so the plot is bounded up front rather than cancelled: at 1,000 objects cmdscale took about 1.6 s and isoMDS about 14 s on the engine, both growing cubically. At most 40 labels are drawn, furthest from the centre first, since past that they stop naming anything.
The biplot uses Gabriel’s distance-preserving scaling on the clustering matrix. prcomp() runs centred but unscaled on the matrix the clustering itself ran on, so the picture is of the geometry the run used; the points are the component scores and the arrows the raw loadings, which is the one scaling of Gabriel’s (1971) family under which the distances between plotted cases approximate the distances the clustering saw. The alternative, covariance-preserving scaling, makes arrow lengths read as standard deviations at the cost of distorting exactly the separation the plot exists to show. Loadings are unit vectors and scores are in data units, so one common factor stretches the longest arrow to 85% of the cloud’s extent – arrow lengths compare with each other, not with the axes. It is withheld under Gower, whose mixed-type frame has no principal components, and in variable mode, where the variables are already the points; past 5,000 cases the cloud is strided within each cluster, keeping every cluster’s share.
Optimal leaf ordering is exact. It is Bar-Joseph et al.'s (2001) algorithm, computed in R by the module, which finds the rotation of every branch that minimises the summed dissimilarity between neighbouring leaves; being exact rather than heuristic, it costs around a second at 200 objects and tens of seconds by 800, more under single linkage.
The bicluster tables read the analysis matrix, except the profiles, and MSR is read against the matrix’s own. Mean value, MSR and the coherence columns are computed on the matrix the algorithm ran on – z-scores when the run standardized – while the bicluster profiles report means on the original scale, which is why the summary column is marked (z) then. MSR carries the matrix’s scale, so a bare value says nothing; the ratio to the whole matrix’s MSR is below 1 exactly when the block is more coherent than the matrix. Avg r leaves out a row constant across the block’s columns, whose correlation is undefined.
The heatmap’s dendrograms are Ward trees on Euclidean distances, and the grid is bounded. Rows and columns are ordered by hclust(dist(x), "ward.D2") on the analysis matrix and its transpose, whatever the biclustering algorithm. The grid is an overview, so past 320 rows – a 640-pixel grid at two pixels a row – the rows are sampled evenly in dendrogram order, each drawn cell still one real observation, and the row dendrogram is withheld since its leaves would not line up; past 8,000 drawn cells the per-cell tooltips cost more than they are worth and are left off.
Missing data
Cases are dropped listwise over the variables the run keeps, whatever the missing-data setting says. Every output of a run rests on one set of objects – the partition, its silhouettes and sums of squares, the tendency tests, the bootstrap’s co-assignment counts – and kmeans(), prcomp() and cmdscale() take no blank at all. A matrix assembled pairwise, each dissimilarity over the variables its two cases share or, in variable mode, each correlation over its own complete cases, would set side by side distances measured on different data, and the validity indices would describe no sample that exists. So the module takes the complete cases before anything reaches R, and the setting’s pairwise default is not honoured here. The pass runs over the variables the run keeps – after the non-numeric ones are split off under an ordinary metric, over every selected variable under Gower – so a column the run never reads costs no cases, and constant variables are judged on the complete cases afterwards. Listwise and imputation are honoured because they act on the dataset before the module sees it. The complete cases carry their original row numbers through the run, so an inserted assignment or membership lands on the case it belongs to and a dropped case stays blank.