このブログでは、統計解析ソフトStataのプログラミングのTipsや便利コマンドを紹介しています.
Facebook groupでは、ちょっとした疑問や気づいたことなどを共有して貰うフォーラムになっています. ブログと合わせて個人の学習に役立てて貰えれば幸いです.
さて、今回は変数生成に便利な関数をご紹介します.いくつかの条件を満たすものを1つの変数にまとめたり、条件式に当てはまるかどうかの二値変数を手軽に生成する方法についてご紹介します.
1.リストアップした変数群をまとめる”inlist”
この”inlist”という関数では名義変数でも数値変数でもリストアップされた値を1つの変数に置き換えたり、あるいはある条件式に放り込んだりするのに使えます.
.generate newvar = 1 if inlist(oldvar, a, b, c, d)
とすると、既存の変数oldvarの値がa, b, c, dのいずれかであるときに新しい変数newvarを1とすることになります.oldvarがString(文字列)であるときには10個までしか列挙できないという縛りがあります.
しかし、以下の方法を使うと10個以上の文字列もhandleできることがわかりました.(いつもお世話になっている東京大学の道端先生にStata FBGで共有していただいたコードを元にしています)
それは、local macroを使うです.具体的には、”levelsof”を使ってその変数の内容を列挙します.これは文字列でも問題無く列挙でき、まとめてlocal macro名をつけることができます.
.levelsof oldvar, local(textlist)
こんな感じで、マクロ名”textlist”なるlocal macroが生み出されます.これを使ってforeachで受け止めればいいのです.local macroの構成要素を取り出すのは、
.foreach tlist of local textlist {
という感じで別のマクロ”tlist”に移します.
clear
/* 架空のデータセットを作る。文字列であるvar1というのを作り、その中身を適当にいれておきます */
input id str50 var1
1 あいうえおかきくけこ
2 さしすせそたちつてと
3 たちつてとなにぬねの
4 はひふへほまみむめも
5 やゆよらりるれろ
6 わおん
7 abcdefghijklmnopqrstuvwxyz
8 ABCDEFGHIJKLMNOP
9 ああいいううええおお
10 かかききくくけけここ
11 ささししすすせせそそ
12 たたちちつつててとと
13 "あいだ くうはく ぜんかくも"
14 あいうえおかきくけこ
end
/* 1と14は中身が一緒になります */
capture noisily list id var1 if ! inlist(var1,"あいうえおかきくけこ","さしすせそたちつてと","たちつてとなにぬねの","はひふへほまみむめも","やゆよらりるれろ","わおん","abcdefghijklmnopqrstuvwxyz","ああいいううええおお","かかききくくけけここ","ささししすすせせそそ","たたちちつつててとと")
/* これだと10個以上なのでエラーがでます "expression too long"といった具合に */
gen checktag=1
levelsof var1, local(textlist) /* var1という変数に含まれるすべての値をtextlistに格納 */
foreach tlist of local textlist {
di "`tlist'"
replace checktag =0 if inlist(var1,"`tlist'") /* tlistに格納しなおしたものをinlistに投入 */
}
list id var1 checktag if checktag==1
これできっちりすべての文字列がリストアップできます。文字列で変な入力がされてしまっているようなデータベースのクリーニングに使えると思います.
2.範囲を指定して置き換える”inrange”
これは数値変数の場合に使えます.
.generate newvar = 1 if inrange(oldvar, a, b)
この条件式で、oldvarがa~bの間にあるとき、新しい変数newvarが1となるように設定できます.このとき、rangeにはイコールが含まれるので、前後の値が含まれますので、イコールを含めたい側に応じて式の順番を考慮する必要があります.
3.条件式に合致するか否かで値を決める”cond”
これはエクセルのifと同じように使うことができます.
generate newvar = 1 if cond(条件式, a, b)
条件式が正ならa, それ以外のときはbとなります.直観的にわかりやすいデスね.
4.まとめ
いかがでしたでしょうか?変数の生成に使える条件設定を楽にするための便利な関数をご紹介しました.まずはお試しあれ!
コメント
stata初心者で勉強させていただいてます。
今回の紹介内容とは少し異なりますが、
var1〜10の10変数の中から、大きい順に3つ抽出する(もしくはその3つだけ残す)
というのはどのようにしたらできるでしょうか?
ご質問ありがとうございます。bysortというコマンドでグループ(個人レベルであればid)ごとに集計します。
最初のステップではまずsortをするのですが、
sort id var
などとやるとidごとに、varの小さい順に並びます。大きい順にしたいときは
gsort id -var
とすれば大きいものから小さいものへの順に並びます。(日付でも応用可能です。)
次のステップで
bysort id: generate n =_n
とやるとidごとに取り出したい変数が順番に並びます。
最後に
drop if n >3
とすれば4番目以降が削除されます。
ごめんなさい、ちょっと誤解してました。横に並ぶ変数の中で大きい順に3つということですよね。
それならば、1つはデータを縦持ちにして上記の方法でお試し頂くとよいです。reshape longで調べてみてください。
もう一つは、max関数ですが、これだと一番大きい値しか取れません。なので同じ作業を繰り返すしかないですかね。自分が思いつくのは、
1、別の変数を作成して、max関数で指定した変数群の中で一番大きい値を置き換える
2、最大値となったものをマイナスとか0に置き換える
3、1と2を繰り返す
ですけど、データを縦持ちに加工した方が早いですね。