
Score every candidate symptom combination
Source:R/score_all_combinations.R
score_all_combinations.RdScores every candidate combination of n_symptoms PCL-5
items against the full DSM-5-TR diagnosis and returns the complete ranked
table – not just the best ones. This is the exhaustive companion to
optimize_combinations /
optimize_combinations_clusters (which keep only the top
n_top): use it to study how performance decays across the whole
candidate set, e.g. to show that many symptom sets are near-interchangeable
(a plateau of near-optimal combinations followed by a drop).
Usage
score_all_combinations(
data,
n_symptoms = 6,
n_required = 4,
clusters = NULL,
score_by = "balanced_accuracy",
chunk_size = 1000,
show_progress = TRUE
)Arguments
- data
A dataframe with the 20 PCL-5 item columns
symptom_1throughsymptom_20(output ofrename_ptsd_columns). Additional carry-through columns are ignored.- n_symptoms
Integer. Number of items per combination (default 6).
- n_required
Integer. How many of the items must be present (score >= 2) for a positive diagnosis (default 4).
- clusters
NULL(default) to score all subsets without a cluster constraint, or a named list of integer vectors (e.g.list(B = 1:5, C = 6:7, D = 8:14, E = 15:20)) for the cluster-constrained candidate set and diagnosis rule.- score_by
Character. Metric that defines the ranking:
"balanced_accuracy"(default),"accuracy", or"sensitivity". All metrics are returned regardless; this only sets the sort order.- chunk_size
Integer. Number of combinations scored per chunk (default 1000). Affects speed and parallel granularity only, never the result.
- show_progress
Logical. If
TRUE(default), display a progress bar (sequential mode only).
Value
A data.frame with one row per candidate combination, sorted
best-to-worst by score_by (ties broken by combination_id
for determinism):
rank: 1 = best.combination_id: sorted item numbers joined by underscores (e.g."1_6_8_10_15_19").tp,fn,fp,tn: the 2x2 counts against the full DSM-5-TR diagnosis.sensitivity,specificity,ppv,npv,accuracy,balanced_accuracy: metrics on the 0-1 scale (NAwhere a denominator is zero).
The attributes n_symptoms, n_required, clusters,
score_by, and n_combinations record the configuration.
Details
With clusters = NULL, all choose(20, n_symptoms) subsets are
scored (38,760 for six symptoms). With a cluster structure, only the
combinations containing at least one item per cluster are scored (13,685
six-symptom sets for the default PCL-5 clusters), and the diagnosis
additionally requires the present symptoms to span all clusters – the same
candidate set and rule as optimize_combinations_clusters.
The hierarchical per-row cluster check makes this mode noticeably slower.
Combinations are processed in chunks. If the future.apply package is
installed and a future plan is set (e.g.
future::plan(future::multisession)), chunks are scored in parallel;
otherwise they are scored sequentially with a progress bar. Results are
identical either way.
The returned combination_id uses the same canonical format as
write_combinations (sorted item numbers joined by
underscores), so the full curve can be joined against exported top-k
combinations.
Examples
# \donttest{
# A 4-symptom search on a 250-row subset keeps the example fast
ptsd_data <- rename_ptsd_columns(simulated_ptsd[1:250, ],
id_col = c("patient_id", "age", "sex"))
curve <- score_all_combinations(ptsd_data, n_symptoms = 4, n_required = 3,
show_progress = FALSE)
nrow(curve) # choose(20, 4) = 4845 combinations, all ranked
#> [1] 4845
head(curve)
#> rank combination_id tp fn fp tn sensitivity specificity ppv npv
#> 1 1 6_7_12_17 227 5 0 18 0.9784483 1 1 0.7826087
#> 2 2 4_6_7_12 226 6 0 18 0.9741379 1 1 0.7500000
#> 3 3 4_6_7_19 225 7 0 18 0.9698276 1 1 0.7200000
#> 4 4 6_7_12_13 225 7 0 18 0.9698276 1 1 0.7200000
#> 5 5 6_7_12_15 225 7 0 18 0.9698276 1 1 0.7200000
#> 6 6 6_7_12_18 225 7 0 18 0.9698276 1 1 0.7200000
#> accuracy balanced_accuracy
#> 1 0.980 0.9892241
#> 2 0.976 0.9870690
#> 3 0.972 0.9849138
#> 4 0.972 0.9849138
#> 5 0.972 0.9849138
#> 6 0.972 0.9849138
# The full balanced-accuracy curve, e.g. for a rank plot:
# plot(curve$rank, curve$balanced_accuracy, type = "l", log = "x")
# }