TSQCA Tutorial (Japanese)

はじめに

TS-QCA(Threshold-Sweep QCA)は、crisp-set QCA において アウトカム Y と条件 X の閾値設定が結果に与える影響を体系的に評価する ためのフレームワークです。

QCA はキャリブレーション後、設定した閾値に基づいて データを 0/1 の集合に分けます。 しかし、閾値が少し変わるだけで、Truth Table や最小化解が変化することがあります。

TS-QCA はその問題に対して、以下を自動実行します。


実装されている4手法

TSQCA パッケージでは、TS-QCA の4つのスイープ手法を実装しています。

手法 変化させる閾値 固定する閾値 目的
CTS–QCA 1つの X Y + 他の X 個別条件の影響を見る
MCTS–QCA 複数の X Y 複数条件の組合せの影響
OTS–QCA Y 全ての X アウトカム閾値の影響
DTS–QCA X と Y なし 全面的感度分析

対象範囲: 本パッケージは十分条件分析に特化しています。必要条件分析(ある条件がアウトカムに必要かどうか)は異なる論理構造と評価指標を伴うため、将来のバージョンで対応予定です。


データ準備

TS-QCA は、キャリブレーション済みデータ(例:0〜10 スケール)を想定しています。 閾値は数値(整数・実数)であれば構いません。

library(TSQCA)
data("sample_data")
dat <- sample_data
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 ...

Yvar  <- "Y"
Xvars <- c("X1", "X2", "X3")

※ 欠損値(NA)が含まれている場合、スイープ実行前に除去または補完を行ってください。


混合データタイプの扱い

2値変数と連続変数が混在する場合

実際の社会科学データでは、2値変数(性別、Yes/No等)と連続変数(売上高、満足度スコア等)が混在することがよくあります。TSQCAでこのような混合データを扱う際には、以下の点に注意が必要です。

基本原則

  1. 2値変数に対して閾値スイープを行わない — すでに2値化されている(0/1)
  2. 2値変数には閾値 1 を指定して元の値を保持する
  3. sweep_listで各変数の閾値を明示的に定義する

なぜ2値変数には閾値1を指定するのか?

内部で使用されるqca_bin()関数は x >= thr で2値化を行います:

  • x = 0 の場合: 0 >= 1 → FALSE → 0(元の値を保持)
  • x = 1 の場合: 1 >= 1 → TRUE → 1(元の値を保持)

これにより、2値変数は2値化プロセスで変更されることなく、元の値が保持されます。

実践例:混合データの場合

データセットに以下の変数があるとします:

  • X1: 性別(0 = 男性、1 = 女性)— 2値変数
  • X2: 商品品質スコア(0-10)— 連続変数
  • X3: 店舗雰囲気スコア(0-10)— 連続変数

ctSweepM()を使用する場合:

# 正しい方法:各変数の閾値を明示的に指定
sweep_list <- list(
  X1 = 1,      # 2値変数: 閾値1を使用
  X2 = 6:8,    # 連続変数: 閾値をスイープ
  X3 = 6:8     # 連続変数: 閾値をスイープ
)

res_mixed <- ctSweepM(
  dat            = dat,
  Yvar           = "Y",
  Xvars          = c("X1", "X2", "X3"),
  sweep_list     = sweep_list,
  thrY           = 7,
  dir.exp        = 1
)

これにより 1 × 3 × 3 = 9通りの閾値組み合わせを探索し、X1は固定された2値条件として、X2とX3はスイープされます。

よくある間違い

# 間違い:2値変数に対してスイープ範囲を指定
sweep_list <- list(
  X1 = 6:8,    # すべての値が0になる(0 < 6 かつ 1 < 6 のため)
  X2 = 6:8,
  X3 = 6:8
)

誤ってX1 = 6:8と指定すると、0も1も>= 6の条件を満たさないため、すべてのX1の値が0になってしまいます。これは2値変数の情報を完全に破壊してしまいます。

推奨方法

閾値スイープを設定する前に、必ずデータ構造を確認してください:

# 変数の範囲を確認
summary(dat[, c("X1", "X2", "X3")])

# 2値変数を識別(0と1のみ)
sapply(dat[, c("X1", "X2", "X3")], function(x) {
  unique_vals <- sort(unique(x))
  if (length(unique_vals) == 2 && all(unique_vals == c(0, 1))) {
    "2値変数(閾値 = 1 を使用)"
  } else {
    paste("連続変数(範囲:", min(x), "-", max(x), ")")
  }
})

CTS–QCA(ctSweepS):単一条件 X スイープ

CTS–QCA は、1つの X 条件の閾値だけを変化させ、 Y とその他の X の閾値は固定したまま、結果の変化を確認する手法です。

sweep_var   <- "X3"   # 閾値を変化させる対象の条件(X)
sweep_range <- 6:9    # 試す閾値候補

thrY         <- 7     # Y の閾値(固定)
thrX_default <- 7     # その他 X の閾値(固定)

res_cts <- ctSweepS(
  dat            = dat,
  Yvar           = "Y",
  Xvars          = c("X1", "X2", "X3"),
  sweep_var      = sweep_var,
  sweep_range    = sweep_range,
  thrY           = thrY,
  thrX_default   = thrX_default,
  dir.exp        = 1,
  return_details = FALSE
)

head(res_cts)
#>   threshold  expression inclS covS
#> 1         6 No solution    NA   NA
#> 2         7 No solution    NA   NA
#> 3         8 No solution    NA   NA
#> 4         9 No solution    NA   NA

MCTS–QCA(ctSweepM):複数条件 X スイープ

MCTS–QCA は、複数の X 条件の閾値を同時に変化させ、 すべての組合せに対して QCA を実行する手法です。

res_mcts <- ctSweepM(
  dat            = dat,
  Yvar           = "Y",
  Xvars          = c("X1", "X2", "X3"),
  sweep_vars     = c("X2", "X3"),
  sweep_range    = 6:9,
  thrY           = 7,
  thrX_default   = 7,
  dir.exp        = 1,
  return_details = FALSE
)
#> Error in ctSweepM(dat = dat, Yvar = "Y", Xvars = c("X1", "X2", "X3"), : unused arguments (sweep_vars = c("X2", "X3"), sweep_range = 6:9, thrX_default = 7)

head(res_mcts)
#> Error: object 'res_mcts' not found

OTS–QCA(otSweep):アウトカム Y のスイープ

OTS–QCA は、アウトカム Y の閾値だけを変化させる手法です。 条件 X の閾値は固定したまま、Y の閾値の取り方が結果に与える影響を評価します。

res_ots <- otSweep(
  dat            = dat,
  Yvar           = "Y",
  Xvars          = c("X1", "X2", "X3"),
  sweep_range    = 6:9,
  thrX           = c(X1 = 7, X2 = 7, X3 = 7),
  dir.exp        = 1,
  return_details = FALSE
)

head(res_ots)
#>   thrY  expression inclS covS
#> 1    6 No solution    NA   NA
#> 2    7 No solution    NA   NA
#> 3    8 No solution    NA   NA
#> 4    9 No solution    NA   NA

DTS–QCA(dtSweep):X×Y 二次元スイープ

DTS–QCA は、X の閾値(複数条件)と Y の閾値を同時に変化させる 最も包括的なスイープ手法です。

sweep_list_dts_X <- list(
  X1 = 6:8,
  X2 = 6:8,
  X3 = 6:8
)

sweep_range_dts_Y <- 6:8

res_dts <- dtSweep(
  dat            = dat,
  Yvar           = "Y",
  Xvars          = c("X1", "X2", "X3"),
  sweep_list_X   = sweep_list_dts_X,
  sweep_range_Y  = sweep_range_dts_Y,
  dir.exp        = 1,
  return_details = FALSE
)

head(res_dts)
#>   combo_id thrY             thrX  expression inclS covS
#> 1        1    6 X1=6, X2=6, X3=6 No solution    NA   NA
#> 2        1    7 X1=6, X2=6, X3=6 No solution    NA   NA
#> 3        1    8 X1=6, X2=6, X3=6 No solution    NA   NA
#> 4        2    6 X1=7, X2=6, X3=6 No solution    NA   NA
#> 5        2    7 X1=7, X2=6, X3=6 No solution    NA   NA
#> 6        2    8 X1=7, X2=6, X3=6 No solution    NA   NA

出力の読み方

各スイープ関数の出力には、概ね次の情報が含まれます。

一般的な解釈の目安:

※ 閾値をわずかに変えただけで最小化解が大きく変化する場合、 その結果は閾値設定に敏感であり、ロバスト性に課題があると判断できます。


まとめ

TSQCA を用いることで、QCA における閾値設定の影響を体系的に評価し、 分析結果のロバスト性を確認できます。

CTS / MCTS / OTS / DTS の各手法により、研究者は:

を実現できます。

References

For more information on TS-QCA methodology, see:

セッション情報

sessionInfo()
#> R version 4.4.1 (2024-06-14 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_0.1.2
#> 
#> loaded via a namespace (and not attached):
#>  [1] cli_3.6.5         knitr_1.50        rlang_1.1.6       xfun_0.52        
#>  [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.29    evaluate_1.0.4    jquerylib_0.1.4  
#> [17] fastmap_1.2.0     yaml_2.3.10       lifecycle_1.0.4   compiler_4.4.1   
#> [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.1       mime_0.13         venn_1.12         cachem_1.1.0