『石油の呪い』の分析では、対象国を低所得国(一人当たりのGDPが5000ドル未満)と、高所得国(同じく5000ドル以上)に分けた分析が多く用いられている。しかし、高所得国に関する分析をRで実行すると、なぜかロスの分析結果と一致しないという現象が見られる。例えば、表2.1(邦訳47ページ)では、政府の規模を産油国と非産油国で比較する時に、低所得国と高所得国の区別が採用されている。この2行目(高所得国)では、非産油国の政府の規模は32.8、産油国では44.6、その差は11.8で5%水準で有意となっている。しかし、Rで分析すると同じ結果にならない。

library(haven)
data<-read_dta("Replication data for The Oil Curse - Ross 2012.dta")
t.test(data$IMFrev[data$gdpcap2000_sup>5000 & data$year==2003]~
         data$oil_gas_value100[data$gdpcap2000_sup>5000 & data$year==2003],var.equal=T)

    Two Sample t-test

data:  data$IMFrev[data$gdpcap2000_sup > 5000 & data$year == 2003] by data$oil_gas_value100[data$gdpcap2000_sup > 5000 & data$year == 2003]
t = -1.131, df = 26, p-value = 0.2684
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -13.671909   3.966845
sample estimates:
mean in group 0 mean in group 1 
       35.68846        40.54099 

 このように、平均値は異なり、また統計的有意性はない。
 この問題の原因は、おそらくロスのプログラムに間違いがあるためと思われる。ここで、その問題を指摘するとともに、正しい分析結果を示す。

ロスの間違い

 ロスが使用したのはStataであり、そのデータとプログラムはHarvard Dataverseからダウンロードできる(https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/Q9AQLU)。ロスが記述したプログラムを参照すると、「人口一人当たりのGDPが5000ドル以上」を抽出する部分に間違いがあることがわかる。
 上記の表2.1の2行目の分析を行うStataのプログラムは、以下のとおりである。

ttest IMF if gdpcap2000_sup>5000 & year==2003, by (oil_gas_value100)

 ttestは平均値の差の検定に用いるStataのコマンドである。次のIMFは引数であり、政府の規模を示す変数IMFrevを指している。Stataでは変数名は後ろから省略可能なので、IMFrevIMFと記述しても、該当する変数が一つであれば問題はない。続くifはRで用いる要素指定[ ]と理解して良い。つまり、gdpcap2000_sup>5000で「gdpcap2000_supが5000より大きい」というデータを指定している。続く&記号で要素指定の条件が追加されており(year==2003)、変数yearが2003のものを指定している。続くbyで平均値の差の検定の2グループを分ける条件が指定される。oil_gas_value100は産油国と非産油国を識別するダミー変数であり、これで産油国と非産油国の間での平均値の差の検定を行っていることになる。
 問題はgdpcap2000_sup>5000の部分である。Stataでは、欠損値は.で示されるが、同時に無限大の数値として扱われる。このため、gdpcap2000_sup>5000と記述すると一人当たりのGDPの値に欠損値を含む観察データをサンプルとして抽出してしまう。ロスのプログラムでは、表2.1の平均値の差の検定では人口一人当たり5000ドル以上の非産油国(2003年)の観察データは22個だが、Rで同じ条件で抽出すると19個である。

data$IMFrev[data$gdpcap2000_sup>5000 & data$year==2003 & data$oil_gas_value100==0]
 [1] 26.75344 46.90000       NA 31.59340 47.10000       NA       NA 35.23825
 [9] 41.37370 46.02120       NA       NA 25.60000 30.92062 42.34221 27.70000
[17] 33.49268 36.20526       NA       NA       NA       NA 22.27604 51.56084
[25]       NA       NA       NA       NA 40.90000 29.39832       NA       NA
[33] 41.74150       NA       NA       NA 20.96332
table(is.na(data$IMFrev[data$gdpcap2000_sup>5000 & data$year==2003 & data$oil_gas_value100==0]))

FALSE  TRUE 
   19    18 

抽出されるサンプルがStataで22個になり、Rで19個になる理由は、ロスのプログラムで、人口一人当たりのGDPが欠損値となっている観察対象を含んでいるからである。このことは、Rで以下のように確認できる。

data$IMFrev[is.na(data$gdpcap2000_sup) & data$year==2003 & data$oil_gas_value100==0]
[1] 16.10526       NA       NA  7.23082       NA 20.60446       NA       NA
[9]       NA
table(is.na(data$IMFrev[is.na(data$gdpcap2000_sup) & data$year==2003 & data$oil_gas_value100==0]))

FALSE  TRUE 
    3     6 

このように、gdpcap2000_supがNAで、2003年のデータであり、尚且つ非産油国のデータは3つ存在する。
本来は19個のデータをサンプルとするところが、22個になってしまったために、平均値の差の検定が正しく出力されなかったのである。

ロスの間違いを再現する

ロスの間違いの原因がgdpcap2000_supのNAを無限大として処理したという上記の説明が正しいのなら、Rで読み込んだロスのデータセットのgdpcap2000_supのNAを無限大のデータに書き換え、Rで平均値の差の検定を行えば、ロスの分析結果と一致するはずである。データを書き換えるため、一時的に別のデータフレームにコピーして検証する。

temp<-data
temp$gdpcap2000_sup[is.na(temp$gdpcap2000_sup)]<-Inf
t.test(temp$IMFrev[temp$gdpcap2000_sup>5000 & temp$year==2003]~
         temp$oil_gas_value100[temp$gdpcap2000_sup>5000 & temp$year==2003],var.equal=T)

    Two Sample t-test

data:  temp$IMFrev[temp$gdpcap2000_sup > 5000 & temp$year == 2003] by temp$oil_gas_value100[temp$gdpcap2000_sup > 5000 & temp$year == 2003]
t = -2.2506, df = 30, p-value = 0.03189
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -22.425154  -1.088447
sample estimates:
mean in group 0 mean in group 1 
       32.81915        44.57595 

これは、『石油の呪い』表2.1の2行目の分析結果と一致する(ここでは掲載しないが、Stataでロスのプログラムを実行した結果と一致する)。
なお、低所得国を対象とした分析には、この問題は発生しない。なぜなら、低所得国の抽出条件はgdpcap2000_sup<5000と記述されており、無限大の値(つまりNA)はこの条件に該当しないからである。

ロスのStataのプログラムを修正する方法

このコンテンツはRで『石油の呪い』を再現することにあり、Stataは対象外である。しかし、ロスのプログラムが間違っていたことをStataで確認するために、正しいプログラムを以下に掲載する。
無限大を削除するためには、条件に<.を追記するだけで良い。これにより、無限大よりも小さい値にサンプルが設定される。つまり、表2.1の2行目のプログラムは、

ttest IMF if gdpcap2000_sup>5000 & gdpcap2000_sup<. & year==2003, by (oil_gas_value100)
となる。

ロスの間違いの影響

 高所得国のサンプルが間違っていることは、『石油の呪い』の議論に大きな影響を与えるだろうか。細かい分析を行わないと正確なことは言えないが、少なくとも一つは間違いの修正が必要となる。それは「第3章 石油の増加、民主主義の後退」において、「こうした傾向が経済的に豊かな国でも貧しい国でも同様に作用することを示しているが、貧しい国においてのみ統計的に有意であることを示している。」(邦訳96ページ)と記述される部分である。「こうした傾向」とは、産油国の方が非産油国よりも民主化する割合が低い傾向を指す。
 この(間違った)部分は、上記で作成したNAを無限大に変換したデータセットを用いることで再現できる。

t.test(temp$ttd_SD[temp$gdpcap2000_sup>5000]~temp$oil_gas_value100[temp$gdpcap2000_sup>5000],alternative="greater",var.equal=T)

    Two Sample t-test

data:  temp$ttd_SD[temp$gdpcap2000_sup > 5000] by temp$oil_gas_value100[temp$gdpcap2000_sup > 5000]
t = 0.93899, df = 1002, p-value = 0.174
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
 -0.004725356          Inf
sample estimates:
mean in group 0 mean in group 1 
    0.013536379     0.007263923 

しかし、正しくは以下の通りである。

t.test(data$ttd_SD[data$gdpcap2000_sup>5000]~data$oil_gas_value100[data$gdpcap2000_sup>5000],alternative="greater",var.equal=T)

    Two Sample t-test

data:  data$ttd_SD[data$gdpcap2000_sup > 5000] by data$oil_gas_value100[data$gdpcap2000_sup > 5000]
t = 2.7574, df = 364, p-value = 0.00306
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
 0.02010994        Inf
sample estimates:
mean in group 0 mean in group 1 
     0.06122449      0.01119403 

非産油国の方が民主化する割合が高いことは変わらないが、その割合はずっと高くなり、また統計的有意性は1%水準で有意である。このため、上記のロスの解釈は、以下のように改められるべきである。

「こうした傾向は経済的に貧しい国でも豊かな国でも統計的に有意であるが、豊かな国でより明確に確認できる。」

 今後も分析内容の精査を続け、新しく修正が必要になった場合には、何らかの手段を通じて公表したい。