超初心者向けのRガイド

QCA. Qualitative Comparative Analysis

Author

SUGINO Isamu, Build with R4.5.1

Published

November 21, 2025

1 全体の構成

2 質的/定性的比較分析

ここでは,定性的比較分析が何であるかと云う事は説明しない。日本語で読める本の一部を紹介するにとどめる。かつては「ブール代数分析」と呼ばれる事が多かった。

また,QCAは現在,大きく分けると,元来のcrisp-set QCA(csQCA)とその後普及したfuzzy-set QCA(fsQCA)があるが,ここではより理解しやすいcrisp-set QCAの初歩をRで実行する方法を解説に留める。
fuzzy-set QCAについて興味があれば以下の書籍を参照の事。

install.packages("QCA")   # 初めての場合は1回だけinstall.packages( )を実行
library(QCA)              # 毎回のRセッションの最初に1回実行

QCAはしばしば,small-Nのcase studyとlarge-Nのquantitative studyの中間のmidium-Nのresearchだと言われるが,large-Nのデータでも全く問題なく実行は出来る。
ここでは統計分析用の演習データを用いて例示する。

d01 <- read.csv("practice.csv")

crisp-set QCAでは原則的には,独立変数(要因factor)も従属変数(帰結outcome)も0-1の二値変数にしなければならない。
また,データにNAがあると実行されない。
要因の数は余り多過ぎてはいけないが,large-Nの場合には通常よりも多くても分析可能ではある1

元々3水準以上ある変数については,どこで二つに区切るかと云う点で判断が必要になる2

summary(d01$age)  # 年齢30-59
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   30.0    39.0    46.0    45.8    52.0    59.0 
d01$senior <- as.numeric(d01$age >= 45)
with(d01, addmargins(table(senior, age, useNA = "ifany")))
      age
senior  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47
   0     3   8   5   7  14  10  13  19   9  10  14  15   4  17  21   0   0   0
   1     0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  16  14  13
   Sum   3   8   5   7  14  10  13  19   9  10  14  15   4  17  21  16  14  13
      age
senior  48  49  50  51  52  53  54  55  56  57  58  59 Sum
   0     0   0   0   0   0   0   0   0   0   0   0   0 169
   1    17  21  13  12  14  16  11  13  13  14  13  15 215
   Sum  17  21  13  12  14  16  11  13  13  14  13  15 384
d01$male <- c(1, 0)[d01$sex]  # 男性ダミー
d01$univ <- d01$edu1          # 四大卒ダミー
d01$full <- c(1, 0, 0, 0)[d01$job] # 正規雇用ダミー
summary(d01[, c("income", "fincome")])   # 本人年収と世帯年収
     income          fincome      
 Min.   :   0.0   Min.   :   0.0  
 1st Qu.:  75.0   1st Qu.: 400.0  
 Median : 300.0   Median : 600.0  
 Mean   : 345.1   Mean   : 720.1  
 3rd Qu.: 500.0   3rd Qu.: 925.0  
 Max.   :2500.0   Max.   :2500.0  
 NA's   :42       NA's   :87      
d01$PInc <- as.numeric(d01$income  >=  500)
d01$FInc <- as.numeric(d01$fincome >= 1000)
with(d01, addmargins(table(PInc,  income, useNA = "ifany")))
      income
PInc     0  25  75 125 200 300 400 500 600 700 800 925 1125 1375 1750 2500 <NA>
  0     45  24  28  29  40  35  31   0   0   0   0   0    0    0    0    0    0
  1      0   0   0   0   0   0   0  29  27  18  12  13    6    1    3    1    0
  <NA>   0   0   0   0   0   0   0   0   0   0   0   0    0    0    0    0   42
  Sum   45  24  28  29  40  35  31  29  27  18  12  13    6    1    3    1   42
      income
PInc   Sum
  0    232
  1    110
  <NA>  42
  Sum  384
with(d01, addmargins(table(FInc, fincome, useNA = "ifany")))
      fincome
FInc     0  25  75 125 200 300 400 500 600 700 800 925 1125 1375 1750 2500 <NA>
  0      5   1   7   8  17  19  28  36  32  27  23  33    0    0    0    0    0
  1      0   0   0   0   0   0   0   0   0   0   0   0   31   13   11    6    0
  <NA>   0   0   0   0   0   0   0   0   0   0   0   0    0    0    0    0   87
  Sum    5   1   7   8  17  19  28  36  32  27  23  33   31   13   11    6   87
      fincome
FInc   Sum
  0    236
  1     61
  <NA>  87
  Sum  384

以下は従属変数(帰結,outcome)の候補。
帰結が数量的な情報である場合,0-1の二値に区切るcut pointについてまず判断が必要になる。

summary(d01$q1502)   # 10段階階層帰属意識,1が上で10が下
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  1.000   5.000   5.000   5.623   7.000  11.000       7 
summary(d01$q1700)   # 11段階幸福度,0が不幸,10が幸福
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  0.000   5.000   7.000   6.694   8.000  11.000       5 
d01$HIGH  <- c(rep(0, 5), rep(1, 5))[d01$q1502]
d01$HAPPY <- c(rep(0, 8), rep(1, 3))[d01$q1700 + 1] # q1700は0を取るので工夫が必要
with(d01, addmargins(table(HIGH,  q1502, useNA = "ifany")))
      q1502
HIGH     1   2   3   4   5   6   7   8   9  10  11 <NA> Sum
  0      2   4  21  66 105   0   0   0   0   0   0    0 198
  1      0   0   0   0   0  68  62  35   6   6   0    0 177
  <NA>   0   0   0   0   0   0   0   0   0   0   2    7   9
  Sum    2   4  21  66 105  68  62  35   6   6   2    7 384
with(d01, addmargins(table(HAPPY, q1700, useNA = "ifany")))
      q1700
HAPPY    0   1   2   3   4   5   6   7   8   9  10  11 <NA> Sum
  0      2   2   4  17  16  65  42  91   0   0   0   0    0 239
  1      0   0   0   0   0   0   0   0  81  41  17   0    0 139
  <NA>   0   0   0   0   0   0   0   0   0   0   0   1    5   6
  Sum    2   2   4  17  16  65  42  91  81  41  17   1    5 384

今回は例示の為,要因と帰結の二値化は以下では固定して扱うが,実際には区切り位置を再検討する必要が生じると考えた方が良い。

データフレイムを完備ケースに限定,変数も使用するものだけに限定。

.full <- with(d01, complete.cases(senior, male, univ, full, PInc, FInc, HIGH, HAPPY))
d02 <- d01[.full, c("senior", "male", "univ", "full", "PInc","FInc", "HIGH", "HAPPY")]

データフレイム名をd02とするので注意。

str(d02, list.len = ncol(d02))
'data.frame':   288 obs. of  8 variables:
 $ senior: num  0 1 1 1 1 1 0 0 0 1 ...
 $ male  : num  1 0 0 1 0 1 0 0 0 0 ...
 $ univ  : int  0 0 0 0 0 0 0 0 0 1 ...
 $ full  : num  1 1 1 1 0 1 0 0 0 0 ...
 $ PInc  : num  1 0 0 1 0 0 0 0 0 0 ...
 $ FInc  : num  0 0 0 1 0 0 1 1 1 0 ...
 $ HIGH  : num  0 1 0 0 0 0 0 0 0 1 ...
 $ HAPPY : num  0 0 0 1 0 0 0 0 1 1 ...
summary(d02)
     senior            male             univ             full       
 Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
 1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000  
 Median :1.0000   Median :0.0000   Median :0.0000   Median :0.0000  
 Mean   :0.5799   Mean   :0.4271   Mean   :0.3125   Mean   :0.4965  
 3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:1.0000  
 Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  
      PInc             FInc             HIGH            HAPPY       
 Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
 1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000  
 Median :0.0000   Median :0.0000   Median :0.0000   Median :0.0000  
 Mean   :0.3438   Mean   :0.2083   Mean   :0.4375   Mean   :0.3993  
 3rd Qu.:1.0000   3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:1.0000  
 Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  

多項選択のパターン集計の方法を活用3

d02$conf <- d02$senior * 10^5 * 1 + 
            d02$male   * 10^4 * 2 +  
            d02$univ   * 10^3 * 3 +
            d02$full   * 10^2 * 4 + 
            d02$PInc   * 10^1 * 5 +
            d02$FInc   * 10^0 * 6 
# 数値型で桁数が多いと指数表記になるので書式設定を指定した文字列変数に変換
d02$CONF <- sprintf("%06d", d02$conf)

各configuration毎に2つの従属変数の平均値(つまり1の値を取るケースの割合)を計算してみる。

cbind(
with(d02, 
     tapply(HIGH, CONF, mean, na.rm = T)),
with(d02, 
     tapply(HAPPY, CONF, mean, na.rm = T))
)
            [,1]      [,2]
000000 0.5312500 0.4375000
000006 0.4285714 0.4285714
000050 0.0000000 1.0000000
000400 0.3076923 0.4615385
000406 0.0000000 1.0000000
003000 0.6000000 0.2000000
003056 0.0000000 1.0000000
003400 0.5000000 0.5000000
003406 0.0000000 1.0000000
003456 1.0000000 0.6666667
020000 0.2500000 0.7500000
020050 0.5000000 0.0000000
020056 0.0000000 0.0000000
020400 0.3750000 0.2500000
020406 0.0000000 0.0000000
020450 0.2500000 0.3333333
023000 0.5000000 0.5000000
023400 0.5000000 0.2500000
023450 0.5000000 0.3125000
023456 0.4000000 0.4000000
100000 0.5416667 0.3541667
100006 0.3333333 0.5000000
100050 0.0000000 1.0000000
100400 0.3636364 0.1818182
100406 0.0000000 1.0000000
100456 0.3333333 1.0000000
103000 0.3750000 0.6250000
103006 0.2500000 0.5000000
103056 0.0000000 0.0000000
103400 0.0000000 0.0000000
103406 0.0000000 1.0000000
103450 0.0000000 1.0000000
103456 0.4000000 0.6000000
120000 1.0000000 0.0000000
120050 0.5000000 0.5000000
120056 1.0000000 1.0000000
120400 0.2000000 0.1000000
120406 0.0000000 1.0000000
120450 0.5714286 0.3571429
120456 0.0000000 1.0000000
123000 0.0000000 0.0000000
123050 0.5000000 0.5000000
123056 0.0000000 0.0000000
123400 1.0000000 0.5000000
123450 0.3750000 0.3125000
123456 0.5714286 0.5714286

度数も知りたい場合は分割表を作成(HAPPYで例示)。

with(d02, table(CONF, HAPPY))
        HAPPY
CONF      0  1
  000000 18 14
  000006  4  3
  000050  0  1
  000400  7  6
  000406  0  1
  003000  4  1
  003056  0  1
  003400  1  1
  003406  0  1
  003456  1  2
  020000  1  3
  020050  2  0
  020056  1  0
  020400  6  2
  020406  1  0
  020450  8  4
  023000  1  1
  023400  3  1
  023450 11  5
  023456  3  2
  100000 31 17
  100006  6  6
  100050  0  2
  100400  9  2
  100406  0  1
  100456  0  3
  103000  3  5
  103006  2  2
  103056  1  0
  103400  2  0
  103406  0  1
  103450  0  1
  103456  2  3
  120000  8  0
  120050  1  1
  120056  0  1
  120400  9  1
  120406  0  1
  120450  9  5
  120456  0  3
  123000  1  0
  123050  1  1
  123056  1  0
  123400  1  1
  123450 11  5
  123456  3  4
Truth Table

それぞれのconfigurationについて,outcomeを0-1に分類する為にcut pointの判断が更に必要になる(incl.cutオプション)。
(ここでは,以下の例示の都合で要因の数や種類,cut pointを選んだ。)

tt01 <- truthTable(d02, outcome = HAPPY, incl.cut = .25,
                   conditions ="senior, male, univ, full, PInc",
                   complete = TRUE)
tt01

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     senior male univ full PInc   OUT    n   incl  PRI  
 1     0     0    0    0    0      1     39  0.436 0.436
 2     0     0    0    0    1      1     1   1.000 1.000
 3     0     0    0    1    0      1     14  0.500 0.500
 4     0     0    0    1    1      ?     0     -     -  
 5     0     0    1    0    0      0     5   0.200 0.200
 6     0     0    1    0    1      1     1   1.000 1.000
 7     0     0    1    1    0      1     3   0.667 0.667
 8     0     0    1    1    1      1     3   0.667 0.667
 9     0     1    0    0    0      1     4   0.750 0.750
10     0     1    0    0    1      0     3   0.000 0.000
11     0     1    0    1    0      0     9   0.222 0.222
12     0     1    0    1    1      1     12  0.333 0.333
13     0     1    1    0    0      1     2   0.500 0.500
14     0     1    1    0    1      ?     0     -     -  
15     0     1    1    1    0      1     4   0.250 0.250
16     0     1    1    1    1      1     21  0.333 0.333
17     1     0    0    0    0      1     60  0.383 0.383
18     1     0    0    0    1      1     2   1.000 1.000
19     1     0    0    1    0      1     12  0.250 0.250
20     1     0    0    1    1      1     3   1.000 1.000
21     1     0    1    0    0      1     12  0.583 0.583
22     1     0    1    0    1      0     1   0.000 0.000
23     1     0    1    1    0      1     3   0.333 0.333
24     1     0    1    1    1      1     6   0.667 0.667
25     1     1    0    0    0      0     8   0.000 0.000
26     1     1    0    0    1      1     3   0.667 0.667
27     1     1    0    1    0      0     11  0.182 0.182
28     1     1    0    1    1      1     17  0.471 0.471
29     1     1    1    0    0      0     1   0.000 0.000
30     1     1    1    0    1      1     3   0.333 0.333
31     1     1    1    1    0      1     2   0.500 0.500
32     1     1    1    1    1      1     23  0.391 0.391

incl: sufficiency inclusion scoreが何であるかを示す。

names(tt01)

[1] “tt” “indexes” “noflevels” “initial.data” “recoded.data” [6] “cases” “DCC” “minmat” “categories” “multivalue”
[11] “options” “fs” “call”

tt01$tt

上述の手動でのconfiguration作成法を使用。
使わない要因の行だけコメントアウトすれば良い。

d02$conf <- d02$senior * 10^5 * 1 + 
            d02$male   * 10^4 * 2 +
            d02$univ   * 10^3 * 3 +
            d02$full   * 10^2 * 4 + 
            d02$PInc   * 10^1 * 5 # +
#           d02$FInc   * 10^0 * 6 

d02$CONF <- sprintf("%05d", d02$conf/10)

with(d02, 
     tapply(HAPPY, CONF, mean, na.rm = T))
    00000     00005     00040     00300     00305     00340     00345     02000 
0.4358974 1.0000000 0.5000000 0.2000000 1.0000000 0.6666667 0.6666667 0.7500000 
    02005     02040     02045     02300     02340     02345     10000     10005 
0.0000000 0.2222222 0.3333333 0.5000000 0.2500000 0.3333333 0.3833333 1.0000000 
    10040     10045     10300     10305     10340     10345     12000     12005 
0.2500000 1.0000000 0.5833333 0.0000000 0.3333333 0.6666667 0.0000000 0.6666667 
    12040     12045     12300     12305     12340     12345 
0.1818182 0.4705882 0.0000000 0.3333333 0.5000000 0.3913043 

ここからわかる様に,crisp-set QCAの結果でのinclの値は,incl.cut = の基準でoutcomeを二値化した場合に,それぞれのconfigurationに該当するcasesのどれだけがoutcome = 1になるかと云う比率を示している。

with(d02, addmargins(table(CONF, HAPPY)))
       HAPPY
CONF      0   1 Sum
  00000  22  17  39
  00005   0   1   1
  00040   7   7  14
  00300   4   1   5
  00305   0   1   1
  00340   1   2   3
  00345   1   2   3
  02000   1   3   4
  02005   3   0   3
  02040   7   2   9
  02045   8   4  12
  02300   1   1   2
  02340   3   1   4
  02345  14   7  21
  10000  37  23  60
  10005   0   2   2
  10040   9   3  12
  10045   0   3   3
  10300   5   7  12
  10305   1   0   1
  10340   2   1   3
  10345   2   4   6
  12000   8   0   8
  12005   1   2   3
  12040   9   2  11
  12045   9   8  17
  12300   1   0   1
  12305   2   1   3
  12340   1   1   2
  12345  14   9  23
  Sum   173 115 288
x1 <- c(5, 5.1, 15.462644)
x2 <- c(5, 15, 50)
x1 # 小数有りをその儘表示
[1]  5.00000  5.10000 15.46264
x2 # 整数のみをその儘表示
[1]  5 15 50
sprintf("デフォルト小数表示 %f", x1)
[1] "デフォルト小数表示 5.000000"  "デフォルト小数表示 5.100000" 
[3] "デフォルト小数表示 15.462644"
sprintf("小数桁数指定 %.3f",     x1)
[1] "小数桁数指定 5.000"  "小数桁数指定 5.100"  "小数桁数指定 15.463"
sprintf("整数として表示 %.0f", x1)
[1] "整数として表示 5"  "整数として表示 5"  "整数として表示 15"
sprintf("整数桁数指定 %03d", x2)
[1] "整数桁数指定 005" "整数桁数指定 015" "整数桁数指定 050"

 分析結果(解solution)は,要因同士の積の項と,それら項の和で表現される。
 要因同士のand 条件を表し,それぞれの要因が単独で・他の要因とは独立して帰結に影響を及ぼすわけではないと云う結合因果(conjunctural causation)を意味する。
 項と項のor 条件を表し,同じ結果を引き起こす因果経路(因果メカニズム)は一つとは限らないと云う多元因果(multiple causation)を意味する4。Raginはこうした考えを多元結合因果(multiple conjunctural causation)と呼んだ5

minimization

 真理表の各行(configuration)から要因同士の積の項が出てきて,通常はそれらが複数行分+で繋がれるが,そこから論理演算で可能な限り簡潔な式に変形する事を最小化と呼ぶ。
 該当するケースが存在しないconfigurationがあった場合に,それをoutcome = 1として扱う場合は include = “?” と云うオプションを指定する6

2025.10.01注記7

minimize(tt01, details = TRUE)

M1: univ*full + senior*~male*~PInc + senior*male*PInc + ~male*~univ*~PInc +
    male*full*PInc + ~senior*~male*~full*PInc + ~senior*male*~full*~PInc +
    (senior*~male*~univ) -> HAPPY 
M2: univ*full + senior*~male*~PInc + senior*male*PInc + ~male*~univ*~PInc +
    male*full*PInc + ~senior*~male*~full*PInc + ~senior*male*~full*~PInc +
    (senior*~univ*PInc) -> HAPPY 

                                                  ------------------- 
                             inclS   PRI   covS   covU   (M1)   (M2)  
--------------------------------------------------------------------- 
1                 univ*full  0.415  0.415  0.235  0.087  0.087  0.087 
2        senior*~male*~PInc  0.391  0.391  0.296  0.061  0.061  0.061 
3          senior*male*PInc  0.435  0.435  0.174  0.009  0.026  0.009 
4         ~male*~univ*~PInc  0.400  0.400  0.435  0.209  0.209  0.209 
5            male*full*PInc  0.384  0.384  0.243  0.035  0.035  0.035 
6  ~senior*~male*~full*PInc  1.000  1.000  0.017  0.017  0.017  0.017 
7  ~senior*male*~full*~PInc  0.667  0.667  0.035  0.035  0.035  0.035 
--------------------------------------------------------------------- 
8        senior*~male*~univ  0.403  0.403  0.270  0.000  0.043        
9         senior*~univ*PInc  0.600  0.600  0.130  0.000         0.043 
--------------------------------------------------------------------- 
                         M1  0.440  0.440  0.957 
                         M2  0.440  0.440  0.957 
tt02 <- minimize(tt01, include = "?", details = TRUE)
tt02

M1: ~male*~univ + univ*full + full*PInc + senior*~male*~PInc + senior*male*PInc +
    ~senior*male*~full*~PInc + (~senior*~male*PInc) -> HAPPY 
M2: ~male*~univ + univ*full + full*PInc + senior*~male*~PInc + senior*male*PInc +
    ~senior*male*~full*~PInc + (~senior*univ*PInc) -> HAPPY 

                                                  ------------------- 
                             inclS   PRI   covS   covU   (M1)   (M2)  
--------------------------------------------------------------------- 
1               ~male*~univ  0.427  0.427  0.487  0.226  0.226  0.235 
2                 univ*full  0.415  0.415  0.235  0.035  0.035  0.035 
3                 full*PInc  0.435  0.435  0.322  0.035  0.035  0.035 
4        senior*~male*~PInc  0.391  0.391  0.296  0.061  0.061  0.061 
5          senior*male*PInc  0.435  0.435  0.174  0.026  0.026  0.026 
6  ~senior*male*~full*~PInc  0.667  0.667  0.035  0.035  0.035  0.035 
--------------------------------------------------------------------- 
7        ~senior*~male*PInc  0.800  0.800  0.035  0.000  0.009        
8         ~senior*univ*PInc  0.400  0.400  0.087  0.000         0.009 
--------------------------------------------------------------------- 
                         M1  0.440  0.440  0.957 
                         M2  0.440  0.440  0.957 
  • inclS: consistency
  • covS: raw coverage
  • covU: unique coverage
names(tt02)
 [1] "tt"         "options"    "negatives"  "initials"   "PIchart"   
 [6] "primes"     "solution"   "essential"  "inputcases" "pims"      
[11] "IC"         "numbers"    "SA"         "complex"    "call"      
tt02$solution
[[1]]
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "~senior*~male*PInc"      
[5] "senior*~male*~PInc"       "senior*male*PInc"        
[7] "~senior*male*~full*~PInc"

[[2]]
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "~senior*univ*PInc"       
[5] "senior*~male*~PInc"       "senior*male*PInc"        
[7] "~senior*male*~full*~PInc"
tt02$essential
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "senior*~male*~PInc"      
[5] "senior*male*PInc"         "~senior*male*~full*~PInc"
tt02$PIchart

                            1  2  3  6  7  8  9  12 13 15 16 17 18 19 20 21 23
~male*~univ                 x  x  x  -  -  -  -  -  -  -  -  x  x  x  x  -  - 
~male*full                  -  -  x  -  x  x  -  -  -  -  -  -  -  x  x  -  x 
univ*full                   -  -  -  -  x  x  -  -  -  x  x  -  -  -  -  -  x 
full*PInc                   -  -  -  -  -  x  -  x  -  -  x  -  -  -  x  -  - 
~senior*~male*PInc          -  x  -  x  -  x  -  -  -  -  -  -  -  -  -  -  - 
~senior*male*univ           -  -  -  -  -  -  -  -  x  x  x  -  -  -  -  -  - 
~senior*univ*PInc           -  -  -  x  -  x  -  -  -  -  x  -  -  -  -  -  - 
senior*~male*~PInc          -  -  -  -  -  -  -  -  -  -  -  x  -  x  -  x  x 
senior*male*PInc            -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
senior*~univ*PInc           -  -  -  -  -  -  -  -  -  -  -  -  x  -  x  -  - 
male*univ*PInc              -  -  -  -  -  -  -  -  -  -  x  -  -  -  -  -  - 
~senior*male*~full*~PInc    -  -  -  -  -  -  x  -  x  -  -  -  -  -  -  -  - 
~senior*~univ*~full*~PInc   x  -  -  -  -  -  x  -  -  -  -  -  -  -  -  -  - 
                            24 26 28 30 31 32
~male*~univ                 -  -  -  -  -  - 
~male*full                  x  -  -  -  -  - 
univ*full                   x  -  -  -  x  x 
full*PInc                   x  -  x  -  -  x 
~senior*~male*PInc          -  -  -  -  -  - 
~senior*male*univ           -  -  -  -  -  - 
~senior*univ*PInc           -  -  -  -  -  - 
senior*~male*~PInc          -  -  -  -  -  - 
senior*male*PInc            -  x  x  x  -  x 
senior*~univ*PInc           -  x  x  -  -  - 
male*univ*PInc              -  -  -  x  -  x 
~senior*male*~full*~PInc    -  -  -  -  -  - 
~senior*~univ*~full*~PInc   -  -  -  -  -  - 

ずっと簡素なモデルで指標の意味を解読してみる。

d02$conf05 <- d02$senior   * 10^2 * 1 +
              d02$male     * 10^1 * 2 +
              d02$univ     * 10^0 * 3

d02$CONF05 <- sprintf("%03d", d02$conf05)

with(d02, tapply(HAPPY, CONF05, mean, na.rm = T))
      000       003       020       023       100       103       120       123 
0.4629630 0.5000000 0.3214286 0.3333333 0.4025974 0.5454545 0.3076923 0.3793103 
with(d02, addmargins(table(CONF05, HAPPY)))
      HAPPY
CONF05   0   1 Sum
   000  29  25  54
   003   6   6  12
   020  19   9  28
   023  18   9  27
   100  46  31  77
   103  10  12  22
   120  27  12  39
   123  18  11  29
   Sum 173 115 288
tt05 <- truthTable(d02, outcome = HAPPY, incl.cut = .45,
           conditions = "senior, male, univ", complete = T)
tt05

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

    senior male univ   OUT    n   incl  PRI  
1     0     0    0      1     54  0.463 0.463
2     0     0    1      1     12  0.500 0.500
3     0     1    0      0     28  0.321 0.321
4     0     1    1      0     27  0.333 0.333
5     1     0    0      0     77  0.403 0.403
6     1     0    1      1     22  0.545 0.545
7     1     1    0      0     39  0.308 0.308
8     1     1    1      0     29  0.379 0.379
Sol05 <- minimize(tt05, include = "?", details = T)
Sol05

M1: ~senior*~male + ~male*univ -> HAPPY

                  inclS   PRI   covS   covU  
-------------------------------------------- 
1  ~senior*~male  0.470  0.470  0.270  0.217 
2     ~male*univ  0.529  0.529  0.157  0.104 
-------------------------------------------- 
              M1  0.489  0.489  0.374 

~senior*~male は真理表の行1, 2を,~male*univ は行2, 6をcoverしている。

  • 真理表行1, 2では,上記の分割表から,29 + 25 + 6 + 6 = 66ケース中,実際に帰結が1になるのは 25 + 6 ケースであり,その比は0.469697となる。これがinclS(consistency)の値である。
  • 真理表行2, 6では0.5294118となる。
  • 帰結が1になるケース数は全部で115である。行1, 2では31ケースある。この比0.2695652がcovS(raw coverage)になっている。行2, 6では0.1565217。
  • 行2はいずれの項にも含まれる。それぞれの項にしか含まれないconfigurationだけでcoverageを計算すると,行1は0.2173913,行6は0.1043478であり,これがcovU(unique coverage)となっている。
tt02

M1: ~male*~univ + univ*full + full*PInc + senior*~male*~PInc + senior*male*PInc +
    ~senior*male*~full*~PInc + (~senior*~male*PInc) -> HAPPY 
M2: ~male*~univ + univ*full + full*PInc + senior*~male*~PInc + senior*male*PInc +
    ~senior*male*~full*~PInc + (~senior*univ*PInc) -> HAPPY 

                                                  ------------------- 
                             inclS   PRI   covS   covU   (M1)   (M2)  
--------------------------------------------------------------------- 
1               ~male*~univ  0.427  0.427  0.487  0.226  0.226  0.235 
2                 univ*full  0.415  0.415  0.235  0.035  0.035  0.035 
3                 full*PInc  0.435  0.435  0.322  0.035  0.035  0.035 
4        senior*~male*~PInc  0.391  0.391  0.296  0.061  0.061  0.061 
5          senior*male*PInc  0.435  0.435  0.174  0.026  0.026  0.026 
6  ~senior*male*~full*~PInc  0.667  0.667  0.035  0.035  0.035  0.035 
--------------------------------------------------------------------- 
7        ~senior*~male*PInc  0.800  0.800  0.035  0.000  0.009        
8         ~senior*univ*PInc  0.400  0.400  0.087  0.000         0.009 
--------------------------------------------------------------------- 
                         M1  0.440  0.440  0.957 
                         M2  0.440  0.440  0.957 

よく見ると,->の左側は最後の項だけが異なり,他は同じである。これはessentialで確認できる。

tt02$essential
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "senior*~male*~PInc"      
[5] "senior*male*PInc"         "~senior*male*~full*~PInc"
tt02$solution
[[1]]
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "~senior*~male*PInc"      
[5] "senior*~male*~PInc"       "senior*male*PInc"        
[7] "~senior*male*~full*~PInc"

[[2]]
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "~senior*univ*PInc"       
[5] "senior*~male*~PInc"       "senior*male*PInc"        
[7] "~senior*male*~full*~PInc"
intersect(tt02$solution[[1]], tt02$solution[[2]])
[1] "~male*~univ"              "univ*full"               
[3] "full*PInc"                "senior*~male*~PInc"      
[5] "senior*male*PInc"         "~senior*male*~full*~PInc"
setdiff(tt02$solution[[1]], tt02$essential)
[1] "~senior*~male*PInc"
setdiff(tt02$solution[[2]], tt02$essential)
[1] "~senior*univ*PInc"
tt02$PIchart

                            1  2  3  6  7  8  9  12 13 15 16 17 18 19 20 21 23
~male*~univ                 x  x  x  -  -  -  -  -  -  -  -  x  x  x  x  -  - 
~male*full                  -  -  x  -  x  x  -  -  -  -  -  -  -  x  x  -  x 
univ*full                   -  -  -  -  x  x  -  -  -  x  x  -  -  -  -  -  x 
full*PInc                   -  -  -  -  -  x  -  x  -  -  x  -  -  -  x  -  - 
~senior*~male*PInc          -  x  -  x  -  x  -  -  -  -  -  -  -  -  -  -  - 
~senior*male*univ           -  -  -  -  -  -  -  -  x  x  x  -  -  -  -  -  - 
~senior*univ*PInc           -  -  -  x  -  x  -  -  -  -  x  -  -  -  -  -  - 
senior*~male*~PInc          -  -  -  -  -  -  -  -  -  -  -  x  -  x  -  x  x 
senior*male*PInc            -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
senior*~univ*PInc           -  -  -  -  -  -  -  -  -  -  -  -  x  -  x  -  - 
male*univ*PInc              -  -  -  -  -  -  -  -  -  -  x  -  -  -  -  -  - 
~senior*male*~full*~PInc    -  -  -  -  -  -  x  -  x  -  -  -  -  -  -  -  - 
~senior*~univ*~full*~PInc   x  -  -  -  -  -  x  -  -  -  -  -  -  -  -  -  - 
                            24 26 28 30 31 32
~male*~univ                 -  -  -  -  -  - 
~male*full                  x  -  -  -  -  - 
univ*full                   x  -  -  -  x  x 
full*PInc                   x  -  x  -  -  x 
~senior*~male*PInc          -  -  -  -  -  - 
~senior*male*univ           -  -  -  -  -  - 
~senior*univ*PInc           -  -  -  -  -  - 
senior*~male*~PInc          -  -  -  -  -  - 
senior*male*PInc            -  x  x  x  -  x 
senior*~univ*PInc           -  x  x  -  -  - 
male*univ*PInc              -  -  -  x  -  x 
~senior*male*~full*~PInc    -  -  -  -  -  - 
~senior*~univ*~full*~PInc   -  -  -  -  -  - 

表頭はoutcome=1となるconfigurationの番号である。

  • 2つの要因だけからなる項は4つある。このうちuniv*fullは31列の為に不可欠,full*PIncは12列の為に不可欠。これらで7, 8, 12, 15, 16, 20, 23, 24, 28, 31, 32がcoverされる。
  • 上記の列を除くと,~male*fullがcoverする列は全て~male*~univでもcoverされているが逆は成り立たないので,~male*~univだけがあれば良い。ここまででcoverされていない列は6, 9, 13, 21, 26, 30。
  • 3つの要因だけからなる項は7つある。列21をcoverするのは全体でsenior*~male*~PIncだけなのでこの項は必須。
  • 列26をcoverするのは全体でsenior*male*PIncとsenior*~univ*PIncだけなのでいずれかは必須。
  • 残る6, 9, 13, 30に着目した時,senior*male*PIncは更に30をcoverしているがsenior*~univ*PIncは何も追加しないので,前者だけあれば足りる。
  • 残るのは列6, 9, 13。列6をcoverするのは全体で~senior*~male*PIncと~senior*univ*PIncだけなのでいずれかは必須。
  • 列9をcoverするのは4つの要因からなる項~senior*male*~full*~PIncと~senior*~univ*~full*~PIncだけなのでいずれかは必須。前者は13もcoverするので前者だけあれば足りる。
  • ここまでで必要とされた項は,~male*~univ,univ*full,full*PInc,senior*~male*~PInc,senior*male*PInc,~senior*male*~full*~PIncの6項。
  • 後は,列6の為に~senior*~male*PIncと~senior*univ*PIncのどちらかがあれば終了。~senior*~male*PIncの方がconsistency = 4/5, ~senior*univ*PIncは(1 + 2 + 7)/(1 + 3 + 21)=0.4なので8,consistencyの観点からは前者の方が良い。

ここでは単なる関数の紹介・例示の為だけにデータや変数,閾値を選択したので,得られた結論を実質的に解釈しようとするとかなり困難である。
要因の選択や帰結の二値化についてはもっと理論的な考察を得て行う必要がある。

# 主な結果をcsvファイルで保存して再利用し易くする。
write.csv(tt02$tt$tt, file = "TruthTable.csv")
write.csv(tt02$PIchart, file = "PIchart.csv")

3 書籍の分析例の再現

田村正紀『経営事例の質的比較分析』

115-118頁の論理的簡単化のデータ

データフレイムの作成

99頁の表4.1より9
但し,テキストでは,要因の並び順が表によって異なり非常に紛らわしいので,115頁で使われている順番に最初から直しておく。

d.tam <- data.frame(
  P = c(0, 0, 1, 1, 1, 1, 1, 0, 0),
  Q = c(0, 0, 1, 0, 1, 1, 0, 0, 1),
  R = c(1, 1, 1, 1, 1, 0, 0, 0, 0),
  S = c(1, 0, 1, 1, 0, 1, 0, 1, 0),
  L = c(1, 0, 1, 1, 1, 1, 0, 0, 0)
)

3.1 Truth Table

 このRのpackageだと,complete の理解は以下の通りだが,テクストでは「不完備真理表」と書かれている。流派の違いかもしれないが,こちらの方が自然だと思う。
 また,configurationの並べ方もテキストは全く規則性がないが,通常はこんな風(もしくはこの逆順)に書いて読み易くする。テクストは表の間での要因の順番も一貫していないが当然一貫させるべき。

t.tam <- truthTable(d.tam, 
                    outcome = L, 
                    complete = TRUE)
t.tam

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     ?     0    -     -  
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000

テクストでは「完備真理表」とされている。

truthTable(d.tam, 
           outcome = L, 
           complete = FALSE)

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 9   1  0  0  0     0     1  0.000 0.000
12   1  0  1  1     1     1  1.000 1.000
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000

他にも incl.cut1 と云うオプションがあるがここでは使い道がない。

3.2 最小化

minimize(t.tam, details = TRUE)

M1: P*Q*R + P*Q*S + ~Q*R*S <-> L

           inclS   PRI   covS   covU  
------------------------------------- 
1   P*Q*R  1.000  1.000  0.400  0.200 
2   P*Q*S  1.000  1.000  0.400  0.200 
3  ~Q*R*S  1.000  1.000  0.400  0.400 
------------------------------------- 
       M1  1.000  1.000  1.000 

outcome L が1となるconfigurationは5つあったが,最少化すると3つの項だけになる。
これが119頁に書かれている。
「最簡解」はどの様に導出されるのか,これでは分からない。
logical remainderを全てLと仮定するとどうなるかを試す。

minimize(t.tam, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

118頁に「最簡解」として書かれているものが導出される。
図4.4の最簡解は,logical remainderを全てL=1とした場合の解と一致する。
 しかし,Truth Tableの1行目,全ての要因が0のものはケースが存在しないが,これのoutcomeが1であるとは流石に想定されないので,これをデータに追加した上でそれ以外のlogical remainderをoutcome = 1として最簡解を導出させると,  

t.tam2 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0)) ,
                     outcome = L, complete = TRUE)
t.tam2

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam2, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

最簡解に一致するのでこれはOK。

3.3 テクストの「最簡解」導出に必要な条件の探索

他のlogical remainder10について幾つか仮定を置いて同様に最簡解を導出してみる。
真理表で OUT が ? となっているconfigurationを一つだけoucome = 0として,他の?はoutcome=1の儘分析してゆく。

t.tam3 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(0, 1, 0, 1, 0)) ,
                     outcome = L, complete = TRUE)
t.tam3

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     0     1  0.000 0.000
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam3, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

最簡解に一致する。

t.tam3 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(0, 1, 1, 0, 0)) ,
                     outcome = L, complete = TRUE)
t.tam3

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     0     1  0.000 0.000
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam3, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

最簡解に一致する。

t.tam3 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(1, 0, 0, 1, 0)) ,
                     outcome = L, complete = TRUE)
t.tam3

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     0     1  0.000 0.000
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam3, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

最簡解に一致する。

t.tam3 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(1, 0, 1, 0, 0)) ,
                     outcome = L, complete = TRUE)
t.tam3

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     0     1  0.000 0.000
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam3, include = "?", details = TRUE)

M1: P*Q + R*S <-> L

        inclS   PRI   covS   covU  
---------------------------------- 
1  P*Q  1.000  1.000  0.600  0.400 
2  R*S  1.000  1.000  0.600  0.400 
---------------------------------- 
    M1  1.000  1.000  1.000 

最簡解に一致する。

(1, 1, 0, 0)をoutcome = 0 と追加する。
t.tam3 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(1, 1, 0, 0, 0)) ,
                     outcome = L, complete = TRUE)
t.tam3

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     0     1  0.000 0.000
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam3, include = "?", details = TRUE)

M1: R*S + (P*R + P*S) <-> L 
M2: R*S + (P*R + Q*S) <-> L 
M3: R*S + (P*S + Q*R) <-> L 
M4: R*S + (Q*R + Q*S) <-> L 

                             --------------------------------- 
        inclS   PRI   covS   covU   (M1)   (M2)   (M3)   (M4)  
-------------------------------------------------------------- 
1  R*S  1.000  1.000  0.600  0.200  0.200  0.200  0.200  0.400 
-------------------------------------------------------------- 
2  P*R  1.000  1.000  0.600  0.000  0.200  0.200               
3  P*S  1.000  1.000  0.600  0.000  0.200         0.200        
4  Q*R  1.000  1.000  0.400  0.000                0.200  0.200 
5  Q*S  1.000  1.000  0.400  0.000         0.200         0.200 
-------------------------------------------------------------- 
    M1  1.000  1.000  1.000 
    M2  1.000  1.000  1.000 
    M3  1.000  1.000  1.000 
    M4  1.000  1.000  1.000 

これは最簡解が再現されない。
これは何かと言うと,PQ~R~SがLにならないと云う仮定だが,これは書籍の「最簡解」と両立しない仮定である事が分かる。逆に言えば,caseとしては観察されていないこのconfigurationについて,これがLとなると仮定しない限り,118, 122頁の最簡解(PQ + RS → L)にはならないと云う事である11

3.4 新たな中間解の検討

以上の検討から,テクストの「最簡解」は受け入れがたい。
しかし,全ての要因が0のconfigurationはoutcome=0として良い様にも思われる。
ここで,outcomeについて(データがないが)推測で値を埋めて解を求める事をやってみる。

t.tam

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     ?     0    -     -  
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     ?     0    -     -  
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000

1行目はOUT=0の仮定が受け入れられるだろう。
他に,8行目は要因が3つ迄揃っているのでOUT=1としても尤もらしそうである。
この2つの追記で,include = “?” を付けずに分析する12

t.tam4 <- truthTable(rbind(d.tam , c(0, 0, 0, 0, 0), c(0, 1, 1, 1, 1)) ,
                     outcome = L, complete = TRUE)
t.tam4

  OUT: output value
    n: number of cases in configuration
 incl: sufficiency inclusion score
  PRI: proportional reduction in inconsistency

     P  Q  R  S    OUT    n  incl  PRI  
 1   0  0  0  0     0     1  0.000 0.000
 2   0  0  0  1     0     1  0.000 0.000
 3   0  0  1  0     0     1  0.000 0.000
 4   0  0  1  1     1     1  1.000 1.000
 5   0  1  0  0     0     1  0.000 0.000
 6   0  1  0  1     ?     0    -     -  
 7   0  1  1  0     ?     0    -     -  
 8   0  1  1  1     1     1  1.000 1.000
 9   1  0  0  0     0     1  0.000 0.000
10   1  0  0  1     ?     0    -     -  
11   1  0  1  0     ?     0    -     -  
12   1  0  1  1     1     1  1.000 1.000
13   1  1  0  0     ?     0    -     -  
14   1  1  0  1     1     1  1.000 1.000
15   1  1  1  0     1     1  1.000 1.000
16   1  1  1  1     1     1  1.000 1.000
minimize(t.tam4, details = TRUE)

M1: R*S + P*Q*R + P*Q*S <-> L

          inclS   PRI   covS   covU  
------------------------------------ 
1    R*S  1.000  1.000  0.667  0.500 
2  P*Q*R  1.000  1.000  0.333  0.167 
3  P*Q*S  1.000  1.000  0.333  0.167 
------------------------------------ 
      M1  1.000  1.000  1.000 

テキストの複雑解,中間解,最簡解のいずれとも異なる解が得られた。
この様に,観測事例の無いパタン(logical remainder)にどの様な仮定を置くかによって結果の解が変化するので,どのパタンは結果が0でどのパタンは結果が1だと仮定したのかを,理由とともに必ず明記すべきであろう。

Footnotes

  1. 要因の数が多いと要因の組合せの種類(configuration)の数は倍々ゲームで増えていくが,それぞれのconfigurationに多少でも該当ケースが有れば分析手続きは可能である↩︎

  2. 言い換えれば裁量の余地がある,もしくは恣意性が発生する。↩︎

  3. 但しここで更にかなり工夫している。↩︎

  4. 等結果性(equifinality)とも呼ばれる。↩︎

  5. 近年では因果的複雑性(causal complexity)と呼ばれる事も多いが,多元結合因果の方が,QCAの特徴を具体的に表現している様に思う。Raginは多元結合因果を,(彼の理解する)統計的データ分析の線形(linear)因果の考え方に鋭く対置させ,統計的データ分析をvariable-oriented,自らの方法をcase-orientedと呼んで後者の優位性を主張した。しかし結合因果は少なくとも部分的には交互作用項として統計的データ分析でも扱いうるし,QCAとロジット分析やログリニア分析の類似性も指摘されている。また,QCAはcase-orientedなのではなくconfiguration-orientedであるとの指摘もある。↩︎

  6. これはデータとして観測されていないもの(QCAはlogical remainderと呼んでいる)について帰結を仮定する事であり,かなり強い前提であるともいえる。こうした前提が尤もらしいかどうかの検討が重要となる。↩︎

  7. Warning in admisc::writePrimeimp(impmat = inputt, mv = mv, collapse = collapse, : Function writePrimeimp() is deprecated, use writePIs().との警告が表示されるが,こちらではどうにもできないので無視する。↩︎

  8. ケース数の違いも大きい為にraw coverage(covS)で言えば後者の方が高いが↩︎

  9. 115頁に「表4.1の真理表から」とあるので。↩︎

  10. 要するにmissing caseと言えばいいだけでは↩︎

  11. 率直に言ってしまえばやや論点先取に思われる。↩︎

  12. 正確に言えば,明示的に指定していない未観測のconfigurationについては全てOUT=0を仮定しているのであり,仮定を置いたり置かなかったりしている訳ではなく,全ての論理残余に1か0のいずれかの仮定を置いている筈である。この点について自覚の弱いものがしばしば見られる。↩︎