ThSQCA 入門 第4回: 結果の報告と確認

ThSQCA
tutorial
閾値スイープを報告にまとめます。generate_report()、構成図、QCAパッケージとの照合、報告のための短いチェックリストを扱います。
Author

Yuki Toyoda

Published

October 5, 2026

最初の3回では、スイープを実行して、読み方を学びました。最終回では、スイープを、報告でき、擁護できる形にします。何を探索したかの記録、構成図、そして、数値がQCAパッケージと一致することの確認です。

library(ThSQCA)
library(QCA)
Loading required package: admisc

To cite package QCA in publications, please use:
  Dusa, Adrian (2019) QCA with R. A Comprehensive Resource.
  Springer International Publishing.
練習用データ(第1回と同じ)
make_demo_data <- function(n = 400, seed = 2026) {
  set.seed(seed)
  clip <- function(x) pmin(10, pmax(0, round(x)))
  QUA <- clip(rnorm(n, 6, 2))
  SER <- clip(rnorm(n, 6, 2))
  ENV <- clip(rnorm(n, 6, 2))
  core <- pmax(pmin(QUA, SER), pmin(QUA, ENV) - 1)
  LOY  <- clip(core + rnorm(n, 0, 0.7))
  data.frame(LOY, QUA, SER, ENV)
}

demo <- make_demo_data()

第1回のアウトカム閾値スイープを、再び使います。今回は、レポートに必要な、完全な詳細を求めます。

res_ots <- otSweep(
  dat            = demo,
  outcome        = "LOY",
  conditions     = c("QUA", "SER", "ENV"),
  sweep_range    = 5:8,
  thrX           = c(QUA = 7, SER = 7, ENV = 7),
  incl.cut       = 0.8,
  n.cut          = 1,
  return_details = TRUE
)

スイープ全体を記録するレポート

スイープは、たくさんの結果を作ります。読み手は、どの範囲を、どの設定で探索し、閾値ごとに何が出たかを、知る必要があります。generate_report() は、それをMarkdownファイルに書き出します。形式は2つあります。

  • "simple" は、本文や付録のための、短いレポートです。要約の表、閾値ごとの解、QCAパッケージで結果を確かめるためのコードが入ります。
  • "full" は、補足資料のためのものです。分析の概要(スイープの範囲と基準値)、記述統計に加えて、閾値ごとに、真理表、解の適合度、項ごとの指標、構成図、QCAパッケージの出力、再現に必要な設定が入ります。そのあとに、閾値どうしの比較が続きます。
report_file <- tempfile(fileext = ".md")
generate_report(res_ots, report_file, dat = demo, format = "simple")

書き出されたファイルの、最初の数行です。自分のコンピュータでは、"ots_report_simple.md" のような、きちんとした名前を付けると、作業フォルダにファイルができます。

cat(head(readLines(report_file), 25), sep = "\n")
# QCA Analysis Report

*(Auto-generated by ThSQCA package)*

**Generated**: 2026-10-08 23:36

---

## Summary

| thrY | expression | inclS | covS | n_solutions |
|---|---|---|---|---|
| 5 | QUA\*SER + QUA\*ENV | 0.981 | 0.403 | 1 |
| 6 | QUA\*SER + QUA\*ENV | 0.926 | 0.565 | 1 |
| 7 | QUA\*SER | 0.894 | 0.656 | 1 |
| 8 | No solution | NA | NA | 0 |


---

## Solutions Overview

### LOY >= 5

**Solution**: QUA\*SER + QUA\*ENV -> LOY

知っておくと便利なオプションがあります。

generate_report(res_ots, "r.md", dat = demo, format = "full")              # more detail
generate_report(res_ots, "r.md", dat = demo, include_chart = FALSE)        # no charts
generate_report(res_ots, "r.md", dat = demo, chart_symbol_set = "latex")   # LaTeX symbols
generate_report(res_ots, "r.md", dat = demo, include_raw_output = FALSE)   # omit QCA output

構成図

QCAの論文では、解を図で示すことがよくあります。経路ごとに1列、条件ごとに1行で、「あり」は塗りつぶした円、「なし」は斜線を入れた円、その経路で条件の存在・不在を限定しないときは、空白にします。経路のリストから、config_chart_from_paths() で描けます。

paths <- c("A*B*~C", "A*D", "B*E")
cat(config_chart_from_paths(paths))
Condition T1 T2 T3
A ● ●
B ● ●
C ⊗
D ●
E ●

● = presence, ⊗ = absence, blank = don’t care

円の記号を印刷できない雑誌などのために、普通の文字がよいなら、ASCII版を使います。

cat(config_chart_from_paths(paths, symbol_set = "ascii"))
Condition T1 T2 T3
A O O
B O O
C X
D O
E O

O = presence, X = absence, blank = don’t care

各閾値の背後に、事例はいくつあるか

スイープの表は、解と適合度の値を示しますが、その背後にある事例の数は示しません。読者がそれを確かめられるようにしておくべきです。ごく少数の事例に支えられた結果は、信頼を下げて読むべきだからです。第1回のアウトカム閾値スイープについて、顧客の数は、ThSQCAを使わずに、データから直接数えられます。図の中の語は英語のままです。

thr <- 5:8
n_out  <- sapply(thr, function(t) sum(demo$LOY >= t))
n_both <- sapply(thr, function(t) sum(demo$LOY >= t & demo$QUA >= 7 & demo$SER >= 7))
cases <- rbind("High loyalty (LOY >= thrY)" = n_out,
               "... and high on QUA and SER" = n_both)
colnames(cases) <- thr

bp <- barplot(cases, beside = TRUE, col = c("#233A9A", "#F28018"),
              ylim = c(0, max(cases) * 1.15),
              xlab = "Outcome threshold (thrY)", ylab = "Number of customers",
              main = "Cases behind each threshold",
              legend.text = rownames(cases),
              args.legend = list(x = "topright", bty = "n", cex = 0.8))
text(bp, cases, labels = cases, pos = 3, cex = 0.8)

グループ化した棒グラフ。アウトカムの閾値5では、ロイヤルティが高い顧客が263人で、そのうち品質とサービスがどちらも高いのは66人。閾値6では177人と65人、閾値7では90人と59人、閾値8では29人と26人。

アウトカムの閾値ごとの、ロイヤルティの高い顧客の数(青)と、そのうち、品質とサービスのどちらも高い顧客の数(オレンジ)。

目標が高くなるにつれて、ロイヤルティの高い群は263人から29人へ小さくなり、スイープの厳しい側の解は、はるかに少ない事例の上に立っています。この件数を、スイープの表の横に報告しておけば、各行がどこまで支えられるかを、簡単に示せます。

QCAパッケージで、セルを確認する

ThSQCAは、新しい結果を作り出すわけではありません。どのセルも、普通のQCA分析なので、どのセルでも、手で再現できます。これは、道具への信頼を築く、よい方法で、査読者に聞かれたときの答えにもなります。ここでは、アウトカム閾値が7のセルを再現します。

bin <- function(x, t) as.integer(x >= t)

d7 <- data.frame(
  LOY = bin(demo$LOY, 7), QUA = bin(demo$QUA, 7),
  SER = bin(demo$SER, 7), ENV = bin(demo$ENV, 7)
)

tt  <- truthTable(d7, outcome = "LOY", conditions = c("QUA", "SER", "ENV"),
                  incl.cut = 0.8, n.cut = 1, show.cases = FALSE)
sol <- minimize(tt)
sol

M1: QUA*SER -> LOY

minimize() が出力した解は、第1回のスイープ表の thrY = 7 の行(QUA*SER)と一致します。どちらも、データを同じ方法で二値化し(得点が7以上なら、集合に入る)、どちらも、同じQCAの関数が最小化を行ったからです。

ソフトウェアのバージョンを記録する

結果は、Rやパッケージのバージョンに左右されることがあります。表示して、レポートと一緒に保管してください。

c(R      = R.version.string,
  QCA    = as.character(packageVersion("QCA")),
  ThSQCA = as.character(packageVersion("ThSQCA")))

スイープを報告するための、短いチェックリスト

スイープは、探索する自由を与えるので、透明であることも求めます。報告する前に、次の問いのすべてに、「はい」と答えられるか、確かめてください。

  1. 閾値の範囲と、値の間隔を、結果を見る前に決めたか。
  2. 固定したすべての設定(一貫性閾値、頻度閾値、解の種類、方向性の期待)を書いたか。
  3. 解がないセルも含めて、格子のすべてのセルを報告したか。
  4. 格子の端のセルの背後に、事例が何件あるかを確かめたか。
  5. あるセルに最小解が複数あったなら、そのことを書いたか。
  6. スイープを、最良の閾値を探す作業として示すことを、避けたか。
  7. R、QCA、ThSQCAのバージョンを記録したか。

ここから先

これで、全体の流れが分かりました。スイープを選び、擁護できる範囲を決め、実行し、読み、報告する、という流れです。さらに学びたい方は、パッケージのドキュメントに、追加の例を含む完全なチュートリアルがあり、手法は論文で説明しています。

使ったソフトウェア: R 4.6.1、QCA 3.25.5、ThSQCA 2.0.9