aregとreghdfeについて
昔からある教科書通りだとStataで固定効果の推定を行うときは、xtreg ..., feを用いる。
しかし、普通の研究者はを使っていない(はずである)。
最近の教科書(松浦, 2021)では、xtregに加えてaregやreghdfeも紹介されている。ちなみに、reghdfeの後半は"High Dimensional Fixed Effect"の略である。
この教科書ではこれらのコードが同じ結果を出力すると紹介されているが、厳密には少し異なっている。また、reghdfeによるメリットが大きいことから近年はreghdfeが最もよく使用されている。
また、普通の回帰分析(reg)に時間や個体のダミー変数を追加することでも同じ結果を得ることができる。
ここまでのまとめ:
固定効果の推定方法は
・xtreg, fe cluster(id)
・areg, absorb(id time) cluster(id)
・reghdfe, absorb(id time) cluster(id)
・reg ... i.id i.time, cluster(id)
の4つがある
これらの4つの違いについてあるが係数の結果は同じであるがクラスター標準誤差が微妙に異なっている。(ふつうの人はクラスター標準誤差を使うと想定している)
まず、xtreg ..., feとaregの比較だが、Cameron and Trivedi (2010, pp259)によるとショートパネルの時はxtreg ..., feが良いとされている。
個人的にxtregが嫌いなので嫌いな理由を説明する。xtregを行う前にxtsetをしておかないといけない。これは、きれいなデータでないとエラーが出るので非常に使いにくい。また、松浦さんのnoteを読んで気づいたのだが、xtregだと個体固定効果しか入っておらず時間についての固定効果は入っていないので
xtreg y $x i.time, fe
と書かないといけない。
これと比較して、その他の3種類はxtsetを行う必要がない。reghdfeはabsorb()オプション(オプションという名前のくせに必須)で個体固定効果と時間固定効果に用いる変数を指定できる。aregもabsorb()を使用できるが変数を1つしか指定できないのが欠点であるため、結局i.idもしくはi.timeを書く必要がある。regはダミー変数(i.id i.time)を追加するだけである。
すなわち、被説明変数をy、説明変数を$x、固定効果をidとtimeということにしておくと
areg y $x i.time, absorb(id) cluster(id)
reghdfe y $x, absorb(id time) cluster(id)
reg y $x i.id i.time, cluster(id)
ということになる。
続いて、reghfdeのメリットについて説明を行う。
これは名前の通り高次の固定効果なので個体×時間の固定効果も簡単に作成できる。やり方は、オプションでabsorb(id#time)とするだけである。つまり、
reghdfe y $x, absorb(id time id#time) cluster(id)
とすることで個体×時間の固定効果を入れられる。
具体例を示す。
use http://www.stata-press.com/data/r9/nlswork.dta
xtset idcode year
qui xtreg ln_wage wks_work age nev_mar not_smsa /*
*/ c_city south union i.year, fe
est sto xtreg
qui reghdfe ln_wage wks_work age nev_mar not_smsa c_city south union, /*
*/ absorb(idcode year)
est sto reghdfe
qui areg ln_wage wks_work age nev_mar not_smsa c_city south union i.year , /*
*/ absorb(idcode) cluster(idcode)
est sto areg
/*時間がかかったので省略
qui reg ln_wage wks_work age nev_mar not_smsa c_city south union i.year i.idcode, /*
*/ cluster(idcode)
est sto reg
*/
ネットに落ちているデータを使用しているので、暇な人はやってみてほしい。変数の説明は本質ではないので飛ばすが、ラベルを見たら書いてあるはずである。また、産業×年の固定効果を追加したいときはオプションを
absorb(id year ind_code#year )と
と変更すればよい。
regだけものすごく時間がかかるのでやらなかったが、結果は下のようになる。
esttab xtreg reghdfe areg, keep(wks_work age nev_mar not_smsa c_city south union) /*
*/ se star(* .1 ** .05 *** .01) mtitles(xtreg reghdfe areg)
------------------------------------------------------------
(1) (2) (3)
xtreg reghdfe areg
------------------------------------------------------------
wks_work 0.00234*** 0.00234*** 0.00234***
(0.000122) (0.000122) (0.000167)
age 0.0237** 0.0237** 0.0237*
(0.0105) (0.0105) (0.0130)
nev_mar -0.0371*** -0.0371*** -0.0371**
(0.0104) (0.0104) (0.0156)
not_smsa -0.0981*** -0.0981*** -0.0981***
(0.0131) (0.0131) (0.0227)
c_city 0.00528 0.00528 0.00528
(0.00895) (0.00895) (0.0143)
south -0.0667*** -0.0667*** -0.0667***
(0.0134) (0.0134) (0.0248)
union 0.0985*** 0.0985*** 0.0985***
(0.00704) (0.00704) (0.0110)
------------------------------------------------------------
N 18835 18153 18835
R-sq 0.130 0.753 0.766
adj. R-sq -0.115 0.695 0.700
------------------------------------------------------------
Standard errors in parentheses
* p<.1, ** p<.05, *** p<.01
aregだけ標準誤差の値が違うもののそれ以外はおなじ結果となっていることがわかる。また、決定係数についてはxtの場合はwithinが表示されているので低くなっている。このあたりはあまり理解できていないので各自調べてほしいが、結局のところ自由度調整済み決定係数を計算してくれているreghdfeの使い勝手が一番良い。
ちなみに、コードをできる限り短くしたいときはこう書く。
global x "wks_work age nev_mar not_smsa c_city south union"
global y ln_wage
reghdfe $y $x, a(id* year) cluster(id*)
global macroを使って変数リストを作成するのと一意に変数名がわかるときは*を使って変数名を省略する。