Performs a grid search over thresholds of multiple X variables.
For each combination of thresholds in sweep_list, the outcome Y
and all X variables are binarized, and a crisp-set QCA is executed.
ctSweepM(
dat,
outcome = NULL,
conditions = NULL,
sweep_list,
thrY,
thrX_default = NULL,
pre_calibrated = NULL,
dir.exp = NULL,
include = "",
incl.cut = 0.8,
n.cut = 1,
pri.cut = 0,
extract_mode = c("first", "all", "essential"),
return_details = TRUE,
Yvar = NULL,
Xvars = NULL
)Data frame containing the outcome and condition variables.
Character. Outcome variable name. Supports negation with
tilde prefix (e.g., "~Y") following QCA package conventions.
Character vector. Names of condition variables.
Named list. Each element is a numeric vector of
candidate thresholds for the corresponding X. Names must match
conditions. Variables listed in pre_calibrated do not
need a sweep_list entry. Every condition must receive a threshold
from one of sweep_list, pre_calibrated, or
thrX_default; a condition covered by none of these raises an
error. To hold a condition at a fixed value while sweeping others, give
it a length-one entry (e.g. list(SPV = 6:8, PRD = 7)).
Numeric. Threshold for Y (fixed).
Numeric or NULL. Threshold used to binarize any
condition that appears in neither sweep_list nor
pre_calibrated, mirroring the argument of the same name in
ctSweepS. Default is NULL, in which case such a
condition is an error rather than being silently dropped.
Character vector or NULL. Names of condition
variables that have been pre-calibrated (e.g., via QCA::calibrate())
and should be passed through to QCA::truthTable() without
binarization. These variables must contain values in the [0, 1]
range. Variables not listed here will be binarized using sweep_list
thresholds as usual. Default is NULL (all variables binarized).
Variables listed here are never swept: they are used as they are. To
sweep a variable that holds membership scores, leave it out of this
argument; it is then binarized at the thresholds you supply (for example
0.3, 0.5, 0.7), like any other numeric variable.
Directional expectations for minimize.
If NULL (default), no directional expectations are applied.
To compute the intermediate solution, specify a numeric vector
(1, 0, or -1 for each condition). Example: dir.exp = c(1, 1, 1)
for three conditions all expected to contribute positively.
Inclusion rule for minimize.
"" (default, QCA compatible) computes the complex solution
without logical remainders.
Use "?" to include logical remainders for parsimonious
(with dir.exp = NULL) or intermediate solutions
(with dir.exp specified).
Consistency cutoff for truthTable.
Frequency cutoff for truthTable.
PRI cutoff for minimize.
Character. How to handle multiple solutions:
"first" (default), "all", or "essential".
See qca_extract for details.
Logical. If TRUE (default), returns both
summary and detailed objects for use with generate_report().
Deprecated. Use outcome instead.
Deprecated. Use conditions instead.
If return_details = FALSE, a data frame with columns:
combo_id — index of the threshold combination
threshold — character string summarizing thresholds,
e.g. "X1=6, X2=7, X3=7"
expression — minimized solution expression
inclS — solution consistency
covS — solution coverage
(additional columns depending on extract_mode)
If return_details = TRUE, a list with:
summary — the data frame above
details — per-combination list of
combo_id, thrX_vec, truth_table, solution
Note that return_details changes the type of the returned
object, not just its contents: with TRUE the summary table is at
result$summary, whereas with FALSE the summary table
is the returned object and result$summary is NULL.
Code intended to work under both settings should branch on
inherits(result, "data.frame") (or simply always pass
return_details = TRUE) rather than assuming result$summary
exists.
# Load sample data
data(sample_data)
# === Three Types of QCA Solutions ===
# Quick demonstration with 2 conditions
sweep_list <- list(X1 = 7, X2 = 7)
# 1. Complex Solution (default, QCA compatible)
result_comp <- ctSweepM(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2"),
sweep_list = sweep_list,
thrY = 7
# include = "" (default), dir.exp = NULL (default)
)
head(result_comp$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=7, X2=7 X1*X2 1 0.3030303 1
# 2. Parsimonious Solution (include = "?")
result_pars <- ctSweepM(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2"),
sweep_list = sweep_list,
thrY = 7,
include = "?" # Include logical remainders
)
head(result_pars$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=7, X2=7 X1*X2 1 0.3030303 1
# 3. Intermediate Solution (include = "?" + dir.exp)
result_int <- ctSweepM(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2"),
sweep_list = sweep_list,
thrY = 7,
include = "?",
dir.exp = c(1, 1) # Positive expectations
)
head(result_int$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=7, X2=7 X1*X2 1 0.3030303 1
# === Threshold Sweep Example ===
# Using 2 conditions and 2 threshold levels
sweep_list <- list(
X1 = 6:7,
X2 = 6:7
)
# Run multiple condition threshold sweep (complex solutions by default)
result_quick <- ctSweepM(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2"),
sweep_list = sweep_list,
thrY = 7
)
head(result_quick$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=6, X2=6 X1*X2 0.8333333 0.4545455 1
#> 2 2 X1=7, X2=6 X1*X2 1.0000000 0.3939394 1
#> 3 3 X1=6, X2=7 No solution NA NA 0
#> 4 4 X1=7, X2=7 X1*X2 1.0000000 0.3030303 1
# Run with negated outcome (~Y)
result_neg <- ctSweepM(
dat = sample_data,
outcome = "~Y",
conditions = c("X1", "X2"),
sweep_list = sweep_list,
thrY = 7
)
head(result_neg$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=6, X2=6 No solution NA NA 0
#> 2 2 X1=7, X2=6 No solution NA NA 0
#> 3 3 X1=6, X2=7 No solution NA NA 0
#> 4 4 X1=7, X2=7 No solution NA NA 0
# \donttest{
# Full multi-condition analysis (27 combinations)
sweep_list_full <- list(
X1 = 6:8,
X2 = 6:8,
X3 = 6:8
)
result_full <- ctSweepM(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_list = sweep_list_full,
thrY = 7
)
head(result_full$summary)
#> combo_id threshold expression inclS covS n_solutions
#> 1 1 X1=6, X2=6, X3=6 X1*X2 0.8333333 0.4545455 1
#> 2 2 X1=7, X2=6, X3=6 X1*X2 1.0000000 0.3939394 1
#> 3 3 X1=8, X2=6, X3=6 X1*X2 1.0000000 0.3030303 1
#> 4 4 X1=6, X2=7, X3=6 X1*X2*~X3 0.8181818 0.2727273 1
#> 5 5 X1=7, X2=7, X3=6 X1*X2 1.0000000 0.3030303 1
#> 6 6 X1=8, X2=7, X3=6 X1*X2 1.0000000 0.2121212 1
# }