STATAでcollapseしても変数の名前をキープする。
異なるobservation間で足し算をしたり、duplicateに対処するためにcollapse
が有用である。しかし、例えば
collapse (sum) population, by(prefecture)
を実行すると、その後の変数prefecture
のラベルは(sum) prefecture
などとなってしまい、もともとprefecture
についていたラベルは消えてしまう。特に変数の数が多いとき改めて全部ラベルを付けなおすのは面倒である。すべての変数で、前の変数名をkeepしたい場合にはまずは以下をcollapse
する前に実行し、名前を記憶させる。
foreach v of var * { local l`v' : variable label `v' if `"`l`v''"' == "" { local l`v' "`v'" } }
そして、collapse
の動作を行った後に、
foreach v of var * { label var `v' "`l`v''" }
を実行すれば、全ての変数が前と同じラベルになる。
STATAでlocal変数の共通部分を抜き出す。
local
は、複数の変数を指定するとき、また、何かの結果を一時保存するのに非常に有用である。その組み合わせ技として、local変数同士から新たなlocal変数を定義したいことがあった(例は一番下)。ここでは、二つのlocalの組から共通の変数を新しいlocalとして定義することを考える。
まずは二つのlocalを定義する。
local cov1 "X1 X2 X3" local cov2 "X2 X3 X4"
(これらのlocalは`cov1'
などとすれば呼び起せる。)そしてこの共通部分である X2 X3を新しいlocalとして定義する。
local common : list cov1 & cov2
display
でうまくいったか確認する。
dis `common'
localはすべて同時に回さないといけないことに注意が必要である。例えば↑をひとつづつ実行しても記憶されない。
STATAで変数や文字列の組でループを回す。
STTAで文字列や変数のループを回すときに使うコード。local
を用いて変数の組を作り、それぞれのグループの何番目かを指定することでループを作る。
例えば、ANCOVAで複数の回帰分析をループで回したいとき、outcomeとbaselineでのoutcomeの組を指定したい。
global controls X1 X2 X3 local Outcomes "Income Asset Expenditure" // local Outcomes_baseline "Income_baseline Asset_baseline Expenditure_baseline" // local n : word count `Outcomes' forvalues i = 1/`n' { local Y : word `i' of `Outcomes' local Yb : word `i' of `Outcomes_baseline' reg `Y' $controls `Yb', robust }
としてやると
reg Income $controls Income_baseline, robust reg Asset $controls Asset_baseline, robust reg Expenditure $controls Expenditure_baseline, robust
を実行したのと同様である。
Stataのegen sum()とgen sum()
変数を作成・加工する際に使用するsum()
関数は、egen
かgen
(またはreplace
)かによって、出力が異なる。
例えば、 以下のようなデータを考える。
id | var1 |
---|---|
a | 1 |
b | 2 |
c | 3 |
この時、egen
とgen
それぞれでvar1
変数をsum()
すると、
egen var1_sum_egen = sum(var1) gen var1_sum_gen = sum(var1)
id | var1 | var1_sum_egen | var1_sum_gen |
---|---|---|---|
a | 1 | 6 | 1 |
b | 2 | 6 | 3 |
c | 3 | 6 | 6 |
となる。つまり、egen ... sum()
では全ての合計値を返す一方で、gen ... sum()
では上の行から順にvar1
を足し上げた値(累積の合計値?)を返す。
ちなみに、replace ... sum()
はgen ... sum()
と挙動は同じ。
STATAで複数の変数をまとめて指定する。
STATAで複数の変数を同時に指定したいときがある。例えば、所得が分類ごとに分かれているときに、それらをすべて足し合わせて総所得を計算するとき(変数を足し合わせるコマンドはここではegen rowtotal
を用いる)などだ。以下では二つの方法を紹介する。
変数リストが
income_agriculture income_labor income_fish income_business
のように入っているとする。
-
を用いて、データセットの順番になっている変数を同時に取り出す。
egen n_SuvCom=rowtotal(income_agriculture - income_business)
とすれば、income_agriculture
からincome_business
までの間の変数を順番にすべて指定できる。ここで注意が必要なのは、順番通りに間の変数をすべて指定するので、間に別の変数が混ざっていたり、データセットをいじったりすると、変わってしまう恐れがある。
*
を用いて、特定の名前の変数をすべて取り出す。
egen n_SuvCom=rowtotal(income_*)
のようにすると、income_
から始まる全ての変数を取り出すことができ、総所得を計算することができる。自分で変数の名前を工夫してつければ便利である。
STATAでlocal変数から特定の変数を落とす
STATAlocal
を用いて変数の組を管理すると何度も入力しなくてよいし、途中で少し違うモデルを回すのが非常に楽になる。
しかしいちいち細かく定義していては全部手で入力しているのとあまり変わらないので、一度定義したものを少し変形して使うことでより綺麗なコードが書ける。ここでは、一度定義したlocal
変数の組からある変数を除く。
例:
local covariate "age sex educ"
と入力することで`covariate'
と入力すれば、age sex educ
の変数の組を呼び出すことができる。ここからeduc
を除いて、age sex
のみの変数の組を使いたいとする。その時、
local educ "educ" local covariate : list covariate - educ
とすれば、`covariate'
はage sex
の組となる。確認するには、
di "`covariate'"
とすればよい。参考:
Stataでデータセット結合:あなたが探しているのは「merge m:m」?それとも「joinby」?
二つのデータセットを、ある変数をkeyとして横方向で結合したい場合、多いと思います。
このkeyがそれぞれのデータセットでunique(被りがない)なら、普段通り、merge 1:1
を使えば問題ありません。
また、一方のデータセットはkeyとなる変数がuniqueになっていて、もう一方のデータセットではkey変数に被りがある場合(例えば、村レベルのデータセットに、家計レベルのデータセットを村IDで結合)、merge 1:m
, merge m:1
、もしくはkey変数に被りがあるデータセットの形を変えてmerge 1:1
してしまう、どの方法でもうまくいくかと思います。
問題が発生するのが、二つのデータセット両方でkey変数がuniqueになっていない時。
例えば、村IDが振られている家計レベルのデータについて、同じ村の中で家計を総当たりで結合したいとします。
その時、データセットの形が各村について家計がlong型ではいっているものを、そのまま結合に使いたいとすると、選択肢となるコマンドは merge m:m
と joinby
です(データセットの形を変えて、merge 1:1
などに落とし込む方法もありますが)。
この二つのコマンド、挙動が全く異なります。
この(総当たりでマッチしたい)時、正解は joinby
です。
merge m:m
では求めている結果を返してくれません。
実際にどんな感じになるか見てみましょう。 例えば、ここでは次のような仮想データを考えます。
data1
id_village | household |
---|---|
1 | A |
1 | B |
2 | A |
2 | B |
data2
id_village | household_2 |
---|---|
1 | A |
1 | B |
2 | A |
2 | B |
この二つのデータをid_village
で横方向で結合すると、
merge m:m id_village using data2
は次のデータを返します:
id_village | household | household_2 |
---|---|---|
1 | A | A |
1 | B | B |
2 | A | A |
2 | B | B |
つまり、key変数の値がuniqueでない時、それぞれのkey変数の値について、上からマッチした順に上から結合していくというものになります(なので、元のデータでの行の順番によって結果が異なります)。 ここから分かるように、総当たりでは結合してくれません。
一方、joinby
だと、
joinby id_village using data2
とすると、次のデータを返します:
id_village | household | household_2 |
---|---|---|
1 | A | A |
1 | A | B |
1 | B | B |
1 | B | A |
2 | A | B |
2 | A | A |
2 | B | B |
2 | B | A |
同じkey変数の値内で、household
と househould_2
が総当たりで結合されています。
ただし、merge
が結合できた行・できなかった行を新たな変数 (_merge
) で明示してくれる一方、joinby
はデフォルトではそうした変数を新たに作りません。
また、data1
, data2
どちらかにしかない id_village
の観測値は、マッチされないため削除されてしまうことにも注意です( merge
では「マッチされない」ということが明示されます)。
ここからも分かる通り、merge m:m
は求めているものと異なる挙動をしている場合が多く、かつ結果が元のデータの行の順番に依存している、危険なコマンドなため、できるだけ使わない方が良いそうです。