Permutation test for whether groups produce different LSA transition
structures. For each pair of groups it pools their sequences,
repeatedly reassigns the group label of whole sequences (preserving
the original group sizes), refits each pseudo-group, and builds a
permutation distribution of the per-edge difference in the chosen
measure. The two-sided p-value is
(1 + #{ |diff_perm| >= |diff_obs| }) / (1 + R) (Phipson & Smyth
2010). A single omnibus test of overall difference is reported from
the same permutations.
Usage
compare_lsa(
x,
y = NULL,
R = 1000L,
measure = c("log_or", "adj_res", "yules_q", "prob", "count", "lift"),
adjust = "none",
min_count = 5L,
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)Arguments
- x
Either an
lsa_groupobject (fromlsa(..., group = )) with two or more groups, or a singlelsafit for the first group.- y
When
xis a singlelsafit, the second group'slsafit. Ignored (and must beNULL) whenxis anlsa_group.- R
Integer. Number of label permutations per comparison. Default
1000.- measure
Character. The per-edge quantity compared between groups. Default
"log_or": the per-cell log odds ratio of the 2x2 transition collapse (Haldane-Anscombe corrected on empty cells) – an N-invariant LSA effect size, so the comparison reflects behaviour rather than sample size. Other options:"yules_q"(also N-invariant, but saturates at +/-1 on zero cells),"adj_res"(adjusted residuals – the LSA test statistic, which scales with sqrt(N) and is therefore confounded by group size; a message warns when groups differ in size),"prob"(transition probabilities – a raw rate, i.e. the TNA quantity, with no independence baseline),"count", or"lift"(observed / expected).- adjust
Multiple-comparison correction; any method accepted by
stats::p.adjust()(e.g."holm","BH","bonferroni"). Default"none". For more than two groups it is applied across the pooled per-edge p-values of all pairs.- min_count
Integer. Minimum pooled observed count (group a + group b) for a transition to be tested. Default
5. Rarer cells carry an unstable odds ratio and a near-degenerate permutation null that produces spurious small p-values, so they getp = NAand are excluded from the multiple-comparison family and the omnibus rather than flagged significant. Set0to test every cell.- parallel
Logical. Use multi-core resampling. Default
FALSE.- n_cores
Integer. Worker count when
parallel = TRUE.- verbose
Logical. Print progress every 100 permutations.
- ...
Reserved.
NA handling. Non-estimable cells (structural zeros, zero-margin rows in a permuted pseudo-group) carry
NAin the measure matrix and are never coerced to zero. Such cells getp_perm = NArather than a spurious significant flag, and the exceedance tally and omnibus statistic are computed withna.rm = TRUE, matchingpermute_lsa().Interpretation caveats. The odds ratio is non-collapsible: the per-group log odds ratios are group-specific departure-from- independence measures and should not be pooled across groups that have different marginal state distributions. As with any LSA, a between-group difference can also be driven by subgroup composition (Simpson's paradox); confirm with subgroup analysis when a confound is plausible.
Value
For two groups, an object of class
c("lsa_comparison", "list") with:
- edges
Tidy per-edge data frame:
from,to, the measure in each group (<measure>_a,<measure>_b), their differencediff(= a - b), the permutation p-valuep_perm, the adjusted p-valuep_adj, and asignificantflag.- global
Omnibus test list:
statistic(observed sum of squared edge differences),p_value, andR.- perm_diff
R x K^2matrix of permuted edge differences.- measure, R, adjust, groups
Call metadata;
groupsis the length-two character vector of group labels (a, b).- fits
The two original fits, named by group.
For more than two groups, an object of class
c("lsa_comparison_pairwise", "list") with:
- edges
Tidy per-edge data frame across all pairs, prefixed by
group_a,group_b;p_adjandsignificantreflect the family-wide correction.- global
One row per pair:
group_a,group_b,statistic,p_value, and the across-pairs adjustedp_adj.- comparisons
Named list of the underlying two-group
lsa_comparisonobjects (each fit withadjust = "none"), for drill-down.- measure, R, adjust, groups
Call metadata;
groupslists all group labels.
Details
With exactly two groups a single comparison is returned. With more
than two groups every pairwise comparison is run and the requested
adjust correction is applied once across the whole family of
per-edge p-values (and separately across the per-pair omnibus tests),
giving family-wise control rather than per-pair control.
References
Phipson, B., & Smyth, G. K. (2010). Permutation p-values should never be zero. Statistical Applications in Genetics and Molecular Biology, 9(1), Article 39.
van Borkulo, C. D., et al. (2022). Comparing network structures on three aspects: A permutation test. Psychological Methods.
Examples
# \donttest{
# group_regulation is wide sequences with no grouping column, so
# derive one: sessions whose first regulation act is planning vs not.
grp <- ifelse(group_regulation$T1 == "plan", "starts_plan", "other")
g <- lsa(group_regulation, group = grp)
cmp <- compare_lsa(g, R = 200)
head(cmp$edges)
#> from to log_or_a log_or_b diff p_perm p_adj
#> 1 adapt adapt -2.934854 -1.22410616 -1.71074827 NA NA
#> 2 cohesion adapt -1.878259 -2.41906008 0.54080059 0.6019900 0.6019900
#> 3 consensus adapt -1.773051 -1.53109175 -0.24195921 0.6865672 0.6865672
#> 4 coregulate adapt -0.309429 -0.09747994 -0.21194909 0.6318408 0.6318408
#> 5 discuss adapt 1.882091 1.89742114 -0.01533041 0.9502488 0.9502488
#> 6 emotion adapt -2.247226 -2.33556543 0.08833958 1.0000000 1.0000000
#> significant
#> 1 FALSE
#> 2 FALSE
#> 3 FALSE
#> 4 FALSE
#> 5 FALSE
#> 6 FALSE
cmp$global
#> $statistic
#> [1] 18.33942
#>
#> $p_value
#> [1] 0.07462687
#>
#> $R
#> [1] 200
#>
# }