Learn R Programming

TSQCA

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:

  • binarizing the data using many threshold candidates
  • generating truth tables
  • applying QCA::minimize()
  • extracting the solution, consistency, and coverage

Implemented sweep types:

  • CTS-QCA (ctSweepS): Sweep the threshold of one X
  • MCTS-QCA (ctSweepM): Sweep thresholds of multiple X conditions
  • OTS-QCA (otSweep): Sweep the threshold of Y only
  • DTS-QCA (dtSweep): Sweep X and Y thresholds simultaneously (2D sweep)

Scope: TSQCA focuses on sufficiency analysis. Necessity analysis is planned for future versions.


Features

Bug Fix for Intermediate Solutions (v1.2.0)

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.

Verification Recommendation for Publications

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.

Solution Type Display and Verification (New in v1.2.0)

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)

Three Types of QCA Solutions (New in v1.1.0)

As of v1.1.0, TSQCA uses the same defaults as QCA::minimize():

Solution Typeincludedir.expLogical RemaindersDescription
Complex (default)""NULLNot usedMost conservative
Parsimonious"?"NULLAll usedMost simplified
Intermediate"?"c(1,1,...)Theory-guidedMost 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 = "?" and dir.exp = c(1, 1, 1).

Multiple Solution Detection

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:

ModeDescriptionUse Case
"first"Returns only the first solution (M1)Default, backward compatible
"all"Returns all solutions concatenatedSee all equivalent solutions
"essential"Returns essential prime implicants common to all solutionsIdentify 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
)

Automatic Report Generation

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

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$)

S3 Methods

All sweep functions return objects supporting S3 class methods:

  • print(): Display analysis overview with solution statistics
  • summary(): Display full results table with parameters
result <- otSweep(...)
print(result)    # Quick overview
summary(result)  # Full details

Negated Outcome Support

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)
)

Terminology Note

TSQCA uses precise Boolean algebra terminology:

TermMeaning
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.md for details.


Installation

install.packages("devtools")
devtools::install_github("im-research-yt/TSQCA")

Relationship with QCA Package

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()
    • Consistency, frequency, and PRI cutoffs for truth table construction
  • include, dir.exp → See QCA::minimize()
    • Inclusion rule and directional expectations for logical minimization

Why This Matters

  • Familiar Workflow: If you know QCA, you already know TSQCA's parameters
  • Detailed Documentation: For in-depth parameter explanations, refer to QCA package documentation
  • Seamless Integration: TSQCA extends QCA without replacing it

Quick Reference

# 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
)

Basic Setup

library(QCA)
library(TSQCA)

dat <- read.csv("sample_data.csv", fileEncoding = "UTF-8")

outcome  <- "Y"
conditions <- c("X1", "X2", "X3")

str(dat)

Working with Mixed Data Types

Handling Binary Variables (0/1)

When your dataset contains both continuous and binary (0/1) variables, special attention is needed:

  • Do NOT use threshold sweep for binary variables — they are already binarized
  • Specify threshold = 1 for binary variables to preserve their original values
  • Explicitly define thresholds for each variable in sweep_list

Why Threshold = 1 for Binary Variables?

The qca_bin() function uses x >= thr for binarization:

  • If x = 0: 0 >= 1 → FALSE → 0 (preserved)
  • If x = 1: 1 >= 1 → TRUE → 1 (preserved)

Example: Mixed Data

# 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.

Common Mistake

# 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.

Usage Examples

1. CTS-QCA: single-condition X sweep (ctSweepS)

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)

2. MCTS-QCA: multi-condition X sweep (ctSweepM)

# 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)

3. OTS-QCA: outcome Y sweep (otSweep)

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")

4. DTS-QCA: 2D sweep of X and Y (dtSweep)

# 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)

Sample Data

data(sample_data)
str(sample_data)

References

Core QCA Methodology

QCA R Package

Robustness and Threshold Sensitivity

  • Oana, I.-E., & Schneider, C. Q. (2024). A Robustness Test Protocol for Applied QCA: Theory and R Software Application. Sociological Methods & Research, 53(1), 57–88. DOI: 10.1177/00491241211036158
  • Oana, I.-E., & Schneider, C. Q. (2018). SetMethods: An Add-on R Package for Advanced QCA. The R Journal, 10(1), 507–533. DOI: 10.32614/RJ-2018-031
  • Skaaning, S.-E. (2011). Assessing the Robustness of Crisp-Set and Fuzzy-Set QCA Results. Sociological Methods & Research, 40(2), 391–408. DOI: 10.1177/0049124111404818
  • Thiem, A., Spöhel, R., & Duşa, A. (2016). Enhancing Sensitivity Diagnostics for Qualitative Comparative Analysis: A Combinatorial Approach. Political Analysis, 24(1), 104–120. DOI: 10.1093/pan/mpv028

Acknowledgements

This package implements methods developed in research supported by JSPS KAKENHI Grant Number JP20K01998.

License

MIT License.

Copy Link

Version

Install

install.packages('TSQCA')

Version

1.3.1

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Yuki Toyoda

Last Published

February 18th, 2026

Functions in TSQCA (1.3.1)

format_qca_term

Format a single QCA term
generate_config_chart

Generate Configuration Chart from QCA Solution
format_qca_solution

Format a QCA solution expression
generate_term_level_chart

Generate solution-term level chart (Fiss-style)
format_qca_solutions

Format multiple QCA solutions
extract_solution_list

Extract solution list from QCA object
extract_paths_from_solution

Extract paths from a single solution
generate_cross_threshold_chart

Generate cross-threshold configuration chart from sweep results
print.tsqca_result

Print method for TSQCA results
generate_threshold_level_chart

Generate threshold-level summary chart
get_all_terms

Get all unique terms from multiple solutions
qca_bin

Binary calibration helper for TSQCA
generate_report

Generate Markdown Report for QCA Analysis
write_full_report

Write full report content
get_condition_status

Determine condition status in a term
parse_solution_terms

Parse solution expression into individual terms
prepare_dat_bin

Prepare analysis data frame for QCA::truthTable()
get_config_labels

Get labels for configuration chart based on language
validate_pre_calibrated

Validate the pre_calibrated parameter
summary.tsqca_result

Summary method for TSQCA results
otSweep

OTS–QCA: Outcome threshold sweep
split_solution_terms

Split solution expression into terms
parse_path_conditions

Parse a single path/term into conditions
sample_data

Sample dataset for TSQCA examples
qca_extract

Extract solution information from a QCA minimization result
identify_epi

Identify Essential Prime Implicants from multiple solutions
write_simple_report

Write simple report content
get_n_solutions

Get the number of intermediate solutions
ctSweepM

MCTS–QCA: Multi-condition threshold sweep
build_config_matrix

Build condition-path matrix for configuration chart
config_chart_multi_solutions

Generate configuration chart for multiple solutions (simple interface)
config_chart_from_paths

Generate configuration chart from paths (simple interface)
ctSweepS

CTS–QCA: Single-condition threshold sweep
dtSweep

DTS–QCA: Two-dimensional X–Y threshold sweep
extract_terms

Extract and format terms from solutions
generate_solution_note

Generate solution note for multiple solutions
SYMBOL_SETS

Symbol sets for configuration charts
add_metrics_rows

Add metrics rows to markdown table
df_to_md_table

Convert data frame to Markdown table
TSQCA-package

TSQCA: Threshold Sweep Extensions for Qualitative Comparative Analysis
extract_solution_metrics_for_chart

Extract solution-level metrics for configuration chart
config_matrix_to_md

Convert configuration matrix to Markdown table
build_single_chart

Build configuration chart for a single solution
escape_md

Escape special characters for Markdown
extract_all_metrics

Extract all metrics from QCA solution object
extract_conditions_from_paths

Extract all unique conditions from paths
extract_path_metrics_for_chart

Extract per-path metrics for configuration chart