2008年4月13日星期日

我常用到的stata命令之五

(续)
合并数据库既要合并观察,又要合并变量。合并观察用append。两个数据库的格式完全一样,但观察不一样,合并他们用append空格using空格(文件名)就可以狗尾续貂了。简单明了,很难犯错。用merge就需要格外小心。如果两个数据库中包含共同的观察,但是变量不同,希望从一个数据库中提取一些变量到另一个数据库,这时用merge。完整的过程如下:

use (文件名) [打开辅助数据库]
sort (变量名) [根据变量排序,这个变量是两个数据库共有的识别信息]
save (文件名), replace [保存辅助数据库]
use (文件名) [打开主数据库]
sort (变量名) [对相同的变量排序]
merge (变量名) using (文件名), keep((变量名))
[第一个变量名即为前面sort后面的变量名,文件名是辅助数据库的名字,后面的变量名是希望提取的变量名]
ta _merge [显示_merge的取值情况。_merge等于1的观察是仅主库有的,等于2的是仅辅助库有的,等于3是两个库都有的。]
drop if _merge==2 [删除仅仅来自辅助库的观察]
drop _merge [删除_merge]
save (文件名), replace [将合并后的文件保存,通常另存]

讲到这里似乎对于数据的生成和处理应该闭嘴了,讲讲估计、检验这些更有趣的事情吧。这里我最后举一个例子,说说准备工作的不易。麻烦的事情是总是有一些没办法简单套用命令的特殊要求。现在有两条路可以通向罗马:一是找到更高级的命令一步到位;二是利用已知简单命令多绕几个圈子达到目的。

下面讲一个惨痛的教训,是我迄今碰到的最繁复的生成新数据。原始数据是一份住户登记表。里面有每个人的个人信息和他与与户主关系的信息,目的是找到亲子关系。构想是新数据库以子辈为观察单位,找到他们的父母,再把父母的变量添加到每个观察上。我的做法如下:

use a1,clear [打开全部样本数据库]
keep if gender==2&agemos>=96&a8~=1&line<10
[保留已婚的一定年龄的女性]
replace a5=1 if a5==0
[变量a5标记和户主的关系。等于0是户主,等于1是户主的配偶。这里不加区分地将户主及其配偶放在一起。]
keep if a5==1|a5==3|a5==7
[保留是户主(=1),是户主的子女(=3),或是户主的儿媳(=7)的那些人。]

ren h hf [将所需变量加上后缀f,表示女性]
ren line lf [将所需变量加上后缀f,表示女性]
sort wave hhid
save b1,replace [排序并保存]

keep if a5f==1 [留下其中是户主或户主配偶的]
save b2,replace [保存]

use b1,clear
keep if a5f==3|a5f==7
save b3,replace [留下其中是户主女儿或儿媳的并保存]

use a3,clear [打开与户主关系是户主子女的儿童数据库]
sort wave hhid
merge wave hhid using CHNS01b2, keep(hf lf)
ta _merge
drop if _merge==2
sort hhid line wave [处理两代户,将户主配偶女性库与儿童库合并]

by hhid line wave: egen x=count(id)
drop x _merge [计算每个年份家庭匹配的情况,x只取值1,表明两代户匹配成功]
save b4,replace [保存]

use a4,clear [打开与户主关系是户主孙子女的儿童数据库]
sort wave hhid
merge wave hhid using CHNS01b3, keep(a5f a8f schf a12f hf agemosf c8f lf)
ta _merge
drop if _merge==2 [处理三代户,将户主女儿或儿媳女性库与孙子女儿童库合并]

sort hhid line wave
by hhid line wave: egen x=count(id)
gen a=agemosf-agemos
drop if a<216&x==3 [计算每个年份家庭匹配的情况,x不只取1,三代户匹配不完全成功。删除不合理的样本,标准是年龄差距和有三个可能母亲的那些家庭。]

gen xx=x[_n+1]
gen xxx=x[_n-1]
gen y=lf if x==1
replace y=lf[_n+1] if x==2&xx==1
replace y=lf[_n-1] if x==2&xxx==1
keep if x==1|(lf==y&x==2)
[对于有两个可能母亲的儿童,有相同编码的女性出现两次的情况。上面的做法是为了保证不删除这部分样本。]

drop a x xx xxx y _merge
save b5,replace [保存合并后的数据库]

[对男性数据的合并完全类似,不赘述。]

log close
exit,clear

我的方法是使用简单命令反复迂回地达到目的,所以非常希望有更简便的方法。不过往往不能追求程序非常漂亮,也得过且过了。曾经有人向我索要过上面的处理方法,但我一直没有回复。现在公开了,希望对需要的人能有所帮助,我也懒得答复了。
(待续)

没有评论: