TSQCA is an R package implementing Threshold-Sweep QCA (TS-QCA), a framework for systematically varying the thresholds used to binarize the outcome and conditions in crisp-set QCA.
After calibration, QCA results may change depending on how thresholds are set. TS-QCA evaluates this sensitivity by automatically:
QCA::minimize() Implemented sweep types:
Scope: TSQCA focuses on sufficiency analysis. Necessity analysis is planned for future versions.
Important: v1.2.0 fixes a critical bug where intermediate solutions were incorrectly extracted when using dir.exp. If you used intermediate solutions in previous versions, please re-run your analyses.
For academic publications, we strongly recommend verifying TSQCA results directly with the QCA package:
library(QCA)
# Run QCA directly to verify TSQCA results
tt <- truthTable(dat, outcome = "Y",
conditions = c("X1", "X2", "X3"),
incl.cut = 0.8)
sol <- minimize(tt, include = "?", dir.exp = c(1, 1, 1))
print(sol) # Compare with TSQCA report output
TSQCA reports include a "QCA Package Output" section for this purpose. Always ensure the solution expressions match before publishing.
Reports now explicitly show the Solution Type (Complex/Parsimonious/Intermediate) and include optional QCA package output for verification:
# Reports now show Solution Type in Analysis Overview
generate_report(result, "report.md", dat = mydata)
# Disable QCA raw output if not needed
generate_report(result, "report.md", dat = mydata, include_raw_output = FALSE)
As of v1.1.0, TSQCA uses the same defaults as QCA::minimize():
| Solution Type | include | dir.exp | Logical Remainders | Description |
|--------------|-----------|-----------|-------------------|-------------|
| Complex (default) | "" | NULL | Not used | Most conservative |
| Parsimonious | "?" | NULL | All used | Most simplified |
| Intermediate | "?" | c(1,1,...) | Theory-guided | Most common in publications |
data(sample_data)
thrX <- c(X1 = 7, X2 = 7, X3 = 7)
# 1. Complex Solution (default)
result_comp <- otSweep(dat = sample_data, outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 7, thrX = thrX)
# 2. Parsimonious Solution
result_pars <- otSweep(dat = sample_data, outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 7, thrX = thrX,
include = "?")
# 3. Intermediate Solution (most common in publications)
result_int <- otSweep(dat = sample_data, outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 7, thrX = thrX,
include = "?", dir.exp = c(1, 1, 1))
Migration from v1.0.0: The default has changed from intermediate to complex solution. To reproduce v1.0.0 behavior, explicitly specify
include = "?"anddir.exp = c(1, 1, 1).
QCA minimization can produce multiple equivalent intermediate solutions. TSQCA detects and reports these cases, allowing researchers to identify robust essential prime implicants versus solution-specific selective prime implicants.
Use the extract_mode parameter to control output:
| Mode | Description | Use Case |
|------|-------------|----------|
| "first" | Returns only the first solution (M1) | Default, backward compatible |
| "all" | Returns all solutions concatenated | See all equivalent solutions |
| "essential" | Returns essential prime implicants common to all solutions | Identify robust findings |
# Detect and show all solutions
result <- otSweep(
dat = mydata,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2 = 7, X3 = 7),
extract_mode = "all" # Show all solutions
)
# Extract essential prime implicants only
result_essential <- otSweep(
dat = mydata,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2 = 7, X3 = 7),
extract_mode = "essential" # Show essential prime implicants
)
The generate_report() function creates comprehensive markdown reports:
# Run analysis with return_details = TRUE (the default)
result <- otSweep(
dat = mydata,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = c(X1 = 7, X2 = 7, X3 = 7)
)
# Generate full report
generate_report(result, "my_analysis.md", dat = mydata, format = "full")
# Generate simple report (for journal manuscripts)
generate_report(result, "my_analysis_simple.md", dat = mydata, format = "simple")
Reports include: - Analysis settings (for reproducibility) - Solution formulas with essential/selective prime implicants - Fit measures (consistency, coverage, PRI) - Cross-threshold comparison tables
Configuration charts are automatically included in reports. Generate Fiss-style configuration charts (Table 5 format):
# Reports include configuration charts by default
generate_report(result, "my_report.md", dat = mydata, format = "full")
# Disable charts if needed
generate_report(result, "my_report.md", dat = mydata, include_chart = FALSE)
# Use LaTeX symbols for academic papers
generate_report(result, "my_report.md", dat = mydata, chart_symbol_set = "latex")
Standalone chart functions are also available:
# From path strings
paths <- c("A*B*~C", "A*D")
chart <- config_chart_from_paths(paths)
cat(chart)
Output:
| Condition | M1 | M2 |
|:--:|:--:|:--:|
| A | ● | ● |
| B | ● | |
| C | ⊗ | |
| D | | ● |
Three symbol sets available: "unicode" (● / ⊗), "ascii" (O / X), "latex" ($\bullet$ / $\otimes$)
All sweep functions return objects supporting S3 class methods:
print(): Display analysis overview with solution statisticssummary(): Display full results table with parametersresult <- otSweep(...)
print(result) # Quick overview
summary(result) # Full details
Analyze conditions sufficient for the absence of an outcome:
# Analyze when Y is low (below threshold)
result <- otSweep(
dat = mydata,
outcome = "~Y", # Tilde prefix for negation
conditions = c("X1", "X2", "X3"),
sweep_range = 6:9,
thrX = c(X1 = 7, X2 = 7, X3 = 7)
)
TSQCA uses precise Boolean algebra terminology:
| Term | Meaning | |------|---------| | Essential Prime Implicants (EPI) | Terms in ALL equivalent solutions (M1, M2...) | | Selective Prime Implicants (SPI) | Terms in SOME solutions only |
Note: This is distinct from Fiss (2011) "Core Conditions" which compares parsimonious vs. intermediate solutions. See
docs/TSQCA_Terminology_Guide_EN.mdfor details.
install.packages("devtools")
devtools::install_github("im-research-yt/TSQCA")
TSQCA is built on top of the QCA package (Duşa, 2019). All function arguments follow QCA conventions:
incl.cut, n.cut, pri.cut → See QCA::truthTable()include, dir.exp → See QCA::minimize()# Check QCA parameter documentation
?QCA::truthTable # For incl.cut, n.cut, pri.cut
?QCA::minimize # For include, dir.exp
# TSQCA uses these same parameters
result <- dtSweep(
dat = sample_data,
outcome = "Y",
conditions = c("X1", "X2"),
sweep_list_X = list(X1 = 6:7, X2 = 6:7),
sweep_range_Y = 6:7,
incl.cut = 0.8, # QCA parameter
n.cut = 1, # QCA parameter
pri.cut = 0 # QCA parameter
)
library(QCA)
library(TSQCA)
dat <- read.csv("sample_data.csv", fileEncoding = "UTF-8")
outcome <- "Y"
conditions <- c("X1", "X2", "X3")
str(dat)
When your dataset contains both continuous and binary (0/1) variables, special attention is needed:
sweep_listThe qca_bin() function uses x >= thr for binarization:
- If x = 0: 0 >= 1 → FALSE → 0 (preserved)
- If x = 1: 1 >= 1 → TRUE → 1 (preserved)
# Suppose X1 is binary (0/1), while X2 and X3 are continuous (0-10)
sweep_list <- list(
X1 = 1, # Binary variable: use threshold 1 to preserve values
X2 = 6:8, # Continuous: sweep thresholds
X3 = 6:8 # Continuous: sweep thresholds
)
res_mcts <- ctSweepM(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_list = sweep_list,
thrY = 7
)
This explores 1 × 3 × 3 = 9 threshold combinations, treating X1 as a fixed binary condition.
# WRONG: Using sweep range for binary variables
sweep_list <- list(
X1 = 6:8, # All values become 0 (since 0 < 6 and 1 < 6)
X2 = 6:8,
X3 = 6:8
)
Best Practice: Always specify thresholds explicitly for each variable based on its data type.
sweep_var <- "X3" # Condition (X) whose threshold will be varied
sweep_range <- 6:9 # Candidate threshold values
thrY <- 7 # Fixed threshold for Y
thrX_default <- 7 # Fixed thresholds for other X's
res_cts <- ctSweepS(
dat = dat,
outcome = outcome,
conditions = conditions,
sweep_var = sweep_var, # X to sweep
sweep_range = sweep_range, # Threshold candidates for X
thrY = thrY, # Fixed Y threshold
thrX_default = thrX_default # Fixed thresholds for other X's
)
summary(res_cts)
# Threshold candidates for each X
sweep_list <- list(
X1 = 6:7,
X2 = 6:7,
X3 = 6:7
)
res_mcts <- ctSweepM(
dat = dat,
outcome = outcome,
conditions = conditions,
sweep_list = sweep_list, # Threshold candidates for each X
thrY = 7 # Fixed Y threshold
)
summary(res_mcts)
thrX <- c(X1 = 7, X2 = 7, X3 = 7) # Fixed thresholds for X
sweep_range_Y <- 6:8 # Candidate thresholds for Y
res_ots <- otSweep(
dat = dat,
outcome = outcome,
conditions = conditions,
sweep_range = sweep_range_Y, # Y threshold candidates
thrX = thrX # Fixed X thresholds
)
summary(res_ots)
# Generate report for detailed analysis
generate_report(res_ots, "ots_report.md", dat = dat, format = "full")
# X-side threshold candidates (multiple conditions)
sweep_list_X <- list(
X1 = 6:7,
X2 = 6:7,
X3 = 6:7
)
# Y-side threshold candidates
sweep_range_Y <- 6:7
res_dts <- dtSweep(
dat = dat,
outcome = outcome,
conditions = conditions,
sweep_list_X = sweep_list_X, # X threshold candidates
sweep_range_Y = sweep_range_Y # Y threshold candidates
)
summary(res_dts)
data(sample_data)
str(sample_data)
This package implements methods developed in research supported by JSPS KAKENHI Grant Number JP20K01998.
MIT License.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.