This document provides reproducible code for TSQCA
analyses.
It is designed to be inserted directly into a research article’s
appendix
or provided as supplementary analysis documentation. All code is fully
executable and ordered for reproducibility.
library(TSQCA)
library(QCA)
#> Warning: package 'QCA' was built under R version 4.4.3
#> Loading required package: admisc
#> Warning: package 'admisc' was built under R version 4.4.3
#>
#> To cite package QCA in publications, please use:
#> Dusa, Adrian (2019) QCA with R. A Comprehensive Resource.
#> Springer International Publishing.
#>
#> To run the graphical user interface, use: runGUI()# Adjust the file name as needed
library(TSQCA)
data("sample_data")
dat <- sample_data
# Outcome and conditions
outcome <- "Y"
conditions <- c("X1", "X2", "X3")
# Quick inspection
str(dat)
#> 'data.frame': 80 obs. of 4 variables:
#> $ Y : int 8 4 5 7 2 2 7 5 3 8 ...
#> $ X1: int 7 2 6 8 8 9 8 8 1 5 ...
#> $ X2: int 7 5 8 4 0 5 8 4 4 2 ...
#> $ X3: int 1 6 6 5 3 4 5 3 6 8 ...
summary(dat)
#> Y X1 X2 X3
#> Min. : 0.000 Min. : 0.000 Min. : 0.00 Min. : 0.000
#> 1st Qu.: 3.000 1st Qu.: 3.000 1st Qu.: 3.00 1st Qu.: 3.000
#> Median : 5.000 Median : 5.500 Median : 5.00 Median : 5.000
#> Mean : 5.513 Mean : 5.237 Mean : 5.05 Mean : 4.925
#> 3rd Qu.: 7.250 3rd Qu.: 8.000 3rd Qu.: 7.25 3rd Qu.: 7.000
#> Max. :10.000 Max. :10.000 Max. :10.00 Max. :10.000thrY_base <- 7
thrX_base <- 7
# Fixed X thresholds (for OTS–QCA)
thrX_vec <- c(
X1 = thrX_base,
X2 = thrX_base,
X3 = thrX_base
)
thrX_vec
#> X1 X2 X3
#> 7 7 7Sweep a single condition X (example: X3).
sweep_var <- "X3" # Condition (X) whose threshold is swept
sweep_range <- 6:9 # Candidate threshold values to evaluate
thrY <- 7 # Outcome (Y) threshold (fixed)
thrX_default <- 7 # Threshold for other X conditions (fixed)
res_cts <- ctSweepS(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_var = "X3",
sweep_range = 6:9,
thrY = 7,
thrX_default = 7,
dir.exp = c(1, 1, 1),
return_details = TRUE
)
summary(res_cts)
#> CTS-QCA Summary
#> ===============
#>
#> Analysis Parameters:
#> Outcome: Y
#> Conditions: X1, X2, X3
#> Consistency cutoff: 0.8
#> Frequency cutoff: 1
#>
#> Results by Threshold:
#>
#> threshold expression inclS covS n_solutions
#> 6 X1*X2 1.000 0.303 1
#> 7 X3 + X1*X2 0.906 0.879 1
#> 8 X3 + X1*X2 1.000 0.818 1
#> 9 X3 + X1*X2 1.000 0.515 1Export:
Sweep multiple X thresholds simultaneously.
# Create a sweep list specifying thresholds for each condition
sweep_list <- list(
X1 = 6:7,
X2 = 6:7,
X3 = 6:7
)
res_mcts <- ctSweepM(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_list = sweep_list,
thrY = 7,
dir.exp = c(1, 1, 1),
return_details = TRUE
)
summary(res_mcts)
#> MCTS-QCA Summary
#> ================
#>
#> Analysis Parameters:
#> Outcome: Y
#> Conditions: X1, X2, X3
#> Consistency cutoff: 0.8
#> Frequency cutoff: 1
#>
#> Results by Threshold:
#>
#> threshold combo_id expression inclS covS n_solutions
#> X1=6, X2=6, X3=6 1 X1*X2 0.833 0.455 1
#> X1=7, X2=6, X3=6 2 X1*X2 1.000 0.394 1
#> X1=6, X2=7, X3=6 3 X1*X2*~X3 0.818 0.273 1
#> X1=7, X2=7, X3=6 4 X1*X2 1.000 0.303 1
#> X1=6, X2=6, X3=7 5 X3 0.864 0.576 1
#> X1=7, X2=6, X3=7 6 ~X1*X3 + X1*X2 0.931 0.818 1
#> X1=6, X2=7, X3=7 7 X3 0.864 0.576 1
#> X1=7, X2=7, X3=7 8 X3 + X1*X2 0.906 0.879 1Export:
Sweep only the outcome threshold (Y).
sweep_range_ots <- 6:8
res_ots <- otSweep(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = sweep_range_ots,
thrX = thrX_vec,
dir.exp = c(1, 1, 1),
return_details = TRUE
)
summary(res_ots)
#> OTS-QCA Summary
#> ===============
#>
#> Analysis Parameters:
#> Outcome: Y
#> Conditions: X1, X2, X3
#> Consistency cutoff: 0.8
#> Frequency cutoff: 1
#>
#> Results by Threshold:
#>
#> thrY expression inclS covS n_solutions
#> 6 X3 + X1*X2 0.906 0.853 1
#> 7 X3 + X1*X2 0.906 0.879 1
#> 8 No solution NA NA 0Export:
Two-dimensional sweep: X thresholds × Y thresholds.
sweep_list_dts_X <- list(
X1 = 6:7,
X2 = 6:7,
X3 = 6:7
)
sweep_range_dts_Y <- 6:7
res_dts <- dtSweep(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_list_X = sweep_list_dts_X,
sweep_range_Y = sweep_range_dts_Y,
dir.exp = c(1, 1, 1),
return_details = TRUE
)
summary(res_dts)
#> DTS-QCA Summary
#> ===============
#>
#> Analysis Parameters:
#> Outcome: Y
#> Conditions: X1, X2, X3
#> Consistency cutoff: 0.8
#> Frequency cutoff: 1
#>
#> Results by Threshold:
#>
#> thrY combo_id thrX expression inclS covS n_solutions
#> 6 1 X1=6, X2=6, X3=6 X1*X2 0.833 0.441 1
#> 7 1 X1=6, X2=6, X3=6 X1*X2 0.833 0.455 1
#> 6 2 X1=7, X2=6, X3=6 X1*X2 1.000 0.382 1
#> 7 2 X1=7, X2=6, X3=6 X1*X2 1.000 0.394 1
#> 6 3 X1=6, X2=7, X3=6 X1*X2*~X3 0.818 0.265 1
#> 7 3 X1=6, X2=7, X3=6 X1*X2*~X3 0.818 0.273 1
#> 6 4 X1=7, X2=7, X3=6 X1*X2 1.000 0.294 1
#> 7 4 X1=7, X2=7, X3=6 X1*X2 1.000 0.303 1
#> 6 5 X1=6, X2=6, X3=7 X3 0.864 0.559 1
#> 7 5 X1=6, X2=6, X3=7 X3 0.864 0.576 1
#> 6 6 X1=7, X2=6, X3=7 ~X1*X3 + X1*X2 0.931 0.794 1
#> 7 6 X1=7, X2=6, X3=7 ~X1*X3 + X1*X2 0.931 0.818 1
#> 6 7 X1=6, X2=7, X3=7 X3 0.864 0.559 1
#> 7 7 X1=6, X2=7, X3=7 X3 0.864 0.576 1
#> 6 8 X1=7, X2=7, X3=7 X3 + X1*X2 0.906 0.853 1
#> 7 8 X1=7, X2=7, X3=7 X3 + X1*X2 0.906 0.879 1Export:
Extract all solutions or essential prime implicants for robustness analysis.
res_essential <- otSweep(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = thrX_vec,
dir.exp = c(1, 1, 1),
extract_mode = "essential",
return_details = TRUE
)
# View results with essential prime implicants, selective terms, and unique terms
head(res_essential$summary)Create comprehensive markdown reports for documentation.
Analyze conditions sufficient for the absence of the outcome.
# Standard: conditions for Y >= threshold
res_Y <- otSweep(
dat = dat,
outcome = "Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = thrX_vec,
dir.exp = c(1, 1, 1)
)
# Negated: conditions for Y < threshold
res_negY <- otSweep(
dat = dat,
outcome = "~Y",
conditions = c("X1", "X2", "X3"),
sweep_range = 6:8,
thrX = thrX_vec,
dir.exp = c(1, 1, 1)
)
# Compare results
res_Y$summary
res_negY$summary
# Check negation flag
res_negY$params$negate_outcome
# [1] TRUEAll parameters are stored for reproducibility.
# View stored parameters
res_ots$params
# Example output:
# $outcome
# [1] "Y"
# $conditions
# [1] "X1" "X2" "X3"
# $thrX
# X1 X2 X3
# 7 7 7
# $incl.cut
# [1] 0.8
# $n.cut
# [1] 1
# $pri.cut
# [1] 0Configuration charts are now automatically included in reports. You can also generate them separately:
# From path strings
paths <- c("A*B*~C", "A*D")
chart <- config_chart_from_paths(paths)
cat(chart)
#> | Condition | M1 | M2 |
#> |:--:|:--:|:--:|
#> | A | ● | ● |
#> | B | ● | |
#> | C | ⊗ | |
#> | D | | ● |
#>
#> *● = presence, ⊗ = absence, blank = don't care*For reports:
# Charts are included by default
generate_report(result, "report.md", dat = dat, format = "full")
# Use LaTeX symbols for academic papers
generate_report(result, "report.md", dat = dat, chart_symbol_set = "latex")For more information on TS-QCA methodology, see:
sessionInfo()
#> R version 4.4.2 (2024-10-31 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26200)
#>
#> Matrix products: default
#>
#>
#> locale:
#> [1] LC_COLLATE=C LC_CTYPE=Japanese_Japan.utf8
#> [3] LC_MONETARY=Japanese_Japan.utf8 LC_NUMERIC=C
#> [5] LC_TIME=Japanese_Japan.utf8
#>
#> time zone: Asia/Tokyo
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] QCA_3.23 admisc_0.39 TSQCA_1.0.0
#>
#> loaded via a namespace (and not attached):
#> [1] cli_3.6.5 knitr_1.50 rlang_1.1.6 xfun_0.55
#> [5] otel_0.2.0 promises_1.5.0 shiny_1.12.1 jsonlite_2.0.0
#> [9] xtable_1.8-4 htmltools_0.5.9 httpuv_1.6.16 sass_0.4.10
#> [13] lpSolve_5.6.23 rmarkdown_2.30 evaluate_1.0.4 jquerylib_0.1.4
#> [17] fastmap_1.2.0 yaml_2.3.10 lifecycle_1.0.4 compiler_4.4.2
#> [21] Rcpp_1.1.0 rstudioapi_0.17.1 later_1.4.4 digest_0.6.39
#> [25] R6_2.6.1 magrittr_2.0.4 bslib_0.9.0 declared_0.25
#> [29] tools_4.4.2 mime_0.13 venn_1.12 cachem_1.1.0