NEWS.md

ctreeMI 1.0.0

0.3.0 introduced the right correction. This release makes it survive contact with real stacked data, and derives the degrees of freedom instead of relying on a p-value that has usually underflowed by the time it is needed. Results will differ from 0.3.0.

ctree_stacked() no longer aborts on large stacked datasets

partykit stores node-level p-values on the natural scale, and they underflow to exactly 0 once the statistic passes roughly 1400 at df = 2. On stacked data that is the normal case, not an edge case: 3,000 rows with M = 30 already produces a root statistic above 5,000. 0.3.0 recovered the degrees of freedom by inverting the stored p-value and, failing that, stopped with

could not recover degrees of freedom at node 1 (statistic = 5187.76,
p = 0). Refusing to prune on unverified statistics.

so the package could not fit the kind of dataset it was written for. 1.0.0 recovers df where the stored p-value is interior and falls back on the structural rule (below) where it is not, and computes the corrected p-value as -expm1(k * pchisq(stat, df, lower.tail = TRUE, log.p = TRUE)), which stays accurate to about 1e-300 rather than collapsing to 0.

Degrees of freedom are derived per node and per candidate variable

With teststat = "quadratic" the node-level statistic is chi-square with df equal to the rank of the covariance matrix of the linear statistic:

ctree_stacked() and prune_stackM() recover an integer df for every candidate variable at every node, by inverting the (statistic, p-value) pairs partykit stored, and cross-check the result against the structural rule.

All candidate variables are tested, not only the one split on

ctree splits a node when any candidate variable meets alpha, and that is the rule the correction must reapply. Rescaling can reorder the candidates, because they carry different degrees of freedom, so the variable with the smallest p-value before the correction is not always the smallest after. node_stats gains p_min and variable_min recording the decisive candidate, and the full per-candidate table is attached as attr(node_stats, "candidates").

Pruning is bottom-up

An internal node is collapsed only once all of its own internal descendants have been collapsed, so a node whose descendant survives the correction keeps its split. This is the compression order described in the paper. Trees will therefore retain some splits that 0.3.0 removed.

prune_stackM() handles a default ctree() fit

ctree_stacked() grows with testtype = "Univariate" so that the stored p-values are raw, but prune_stackM() is documented as accepting any tree fitted on stacked data, and partykit's default is testtype = "Bonferroni", where the stored p-values already carry the multiplicity adjustment. Inverting those as if they were raw returned a plausible but wrong df (2.32 instead of 2; 12.05 instead of 8 in testing) and the internal verification could not detect it, because it re-solved the same equation it had just inverted. 1.0.0 reads the multiplicity setting from the fitted control and inverts the matching relationship, and check_stackM_extraction() now exercises both settings and checks the recovered df against the structural rule rather than against itself.

rescale_alpha() is removed

It implemented the alpha / M rule from 0.1.0-0.2.0, which is not the Stack/M correction, and by 0.3.0 its entire help page was an explanation of why not to use it. Deprecating it kept a function in the index whose only purpose was to document a mistake. Code that still calls it will now fail with could not find function "rescale_alpha"; the replacement is [rescale_statistic()], or [ctree_stacked()], which applies the correct rule automatically.

Other changes

ctreeMI 0.3.0

Correctness fix -- please refit any tree produced by 0.1.0 or 0.2.0

Versions 0.1.0 and 0.2.0 did not implement the Stack/M correction of Sherlock et al. (2026). They divided the significance threshold by M and passed alpha / M to ctree_control(). The published and validated method divides the node-level chi-square statistic by M and recomputes the p-value.

These are not equivalent. Writing q(p, df) for the chi-square quantile function, the statistic rule rejects when X > M * q(1 - alpha, df) while the threshold rule rejects when X > q(1 - alpha / M, df). They coincide only at M = 1. At df = 1 and alpha = 0.05:

| M | statistic rule | threshold rule | |----|----------------|----------------| | 5 | X > 19.2 | X > 6.63 | | 10 | X > 38.4 | X > 7.88 | | 30 | X > 115.2 | X > 9.88 | | 50 | X > 192.1 | X > 10.83 |

Threshold rescaling therefore under-corrects severely, and trees fitted with 0.1.0-0.2.0 contain more splits than the published method supports. Refit any such tree with 0.3.0 and re-check any reported subgroups.

Changes

ctreeMI 0.2.0

ctreeMI 0.1.0



Try the ctreeMI package in your browser

Any scripts or data that you put into this service are public.

ctreeMI documentation built on July 27, 2026, 5:08 p.m.