CFPS数据处理:少儿代答库与成人库匹配
👇 连享会 · 推文导航 | www.lianxh.cn
🍎 Stata:Stata基础 | Stata绘图 | Stata程序 | Stata新命令 📘 论文:数据处理 | 结果输出 | 论文写作 | 数据分享 💹 计量:回归分析 | 交乘项-调节 | IV-GMM | 时间序列 | 面板数据 | 空间计量 | Probit-Logit | 分位数回归 ⛳ 专题:SFA-DEA | 生存分析 | 爬虫 | 机器学习 | 文本分析 🔃 因果:DID | RDD | 因果推断 | 合成控制法 | PSM-Matching 🔨 工具:工具软件 | Markdown | Python-R-Stata 🎧 课程:公开课-直播 | 计量专题 | 关于连享会
连享会 · 文本分析 | 爬虫 | 机器学习
作者:周小强 (中南财经政法大学)
邮箱:zhouxiaoqiang1017@163.com
目录
1. 引言
2. 数据获取
3. 匹配思路
4. 匹配步骤
5. 变量计算
6. 相关推文
温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:
1. 引言
本文主要有两个目标:
第一,将 CFPS 少儿代答库与成人库进行匹配; 第二,围绕子女数量计算一些在未来研究中可能用到的变量,如成年子女数量、未成年子女数量、男孩数量、女孩数量、 0-3 岁子女数量等。
本文后续将围绕上述两个目标展开,并以 2018 年 CFPS 数据为例展示相关过程。
2. 数据获取
读者可自行前往「CFPS 数据平台」或「北京大学开放研究数据平台」,依步骤注册账号、下载数据。详细的数据介绍可在「CFPS 官网」查看。
3. 匹配思路
在介绍匹配思路前,先对 CFPS 数据库作简单介绍。2018 年 CFPS 数据库包含五个子库,分别是个人库、家庭成员库、家庭经济库、跨年核心变量库和少儿家长代答库。其中,家庭成员库包含所有个体 (含儿童) 及其对应子女 (如果有子女) 的 ID 信息,部分变量布局如下:
. use cfps2018famconf_202008, clear
. des pid*
Variable Storage Display Value
name type format label Variable label
-------------------------------------------------------------
pid double %20.0g 个人样本编码
pid_a_c1 double %12.0g pid_a_c1 孩子1样本编码
pid_a_c2 double %12.0g pid_a_c2 孩子2样本编码
pid_a_c3 double %12.0g pid_a_c3 孩子3样本编码
pid_a_c4 double %12.0g pid_a_c4 孩子4样本编码
pid_a_c5 double %12.0g pid_a_c5 孩子5样本编码
pid_a_c6 double %12.0g pid_a_c6 孩子6样本编码
pid_a_c7 double %12.0g pid_a_c7 孩子7样本编码
pid_a_c8 double %12.0g pid_a_c8 孩子8样本编码
pid_a_c9 double %12.0g pid_a_c9 孩子9样本编码
pid_a_c10 double %12.0g pid_a_c10 孩子10样本编码
其中,少儿代答库包含了所有 0-15 岁少儿的家长代答数据,每个被访问到的孩子为一行,以 pid 标识。个人库收录了 10 岁及以上受访者的个人信息,如性别、年龄等。本文使用家庭成员库、少儿家长代答库和个人库来匹配少儿代答与成人数据。具体思路如下:
将家庭成员库作为 master data,少儿代答库和个人库作为 using data; 用家庭成员库中每个孩子的样本编码与少儿代答库中的 pid 进行匹配。若孩子 i 的样本编码能够与少儿代答库中的 pid 配对,则说明孩子 i 存在代答信息; 因为家庭成员库中设有 10 个孩子的样本编码,故需循环匹配 10 次。需要说明的是,在每次匹配后要删除 _merge=2 的样本,这主要是为了保证每次匹配时 master data 的样本量相同; 使用 pid 作为匹配变量,对个人库进行匹配; 删除年龄小于 18 岁的个体,即得到成人与少儿代答相匹配的数据。
4. 匹配步骤
首先,依据「CFPS 数据平台」提供的少儿代答库,使用 forvalues
命令生成 10 个子数据集,以便后续匹配使用。
. * 生成 10 个少儿代答库子集
. forvalues i = 1(1)10{
2. use cfps2018childproxy_202012, clear //导入少儿家长代答数据库
3. keep pid wb202 wb203 //保留需要的少儿信息, 如果还需要其他信息, 可根据需要进行保留
4. renvars _all, postfix(_`i') //给所有的变量加后缀
5. rename pid_`i' pid_a_c`i' //变量重命名, 以保证匹配变量在 master 和 using 中一致
6. save child`i', replace
7. }
然后,将家庭成员库作为 master data,少儿代答库作为 using data 进行匹配。
. * 匹配少儿代答与成人库
. use cfps2018famconf_202008, clear //导入家庭成员数据库
. forvalues i= 1(1)10{
2. merge m:1 pid_a_c`i' using child`i' //因家庭成员库有父亲和母亲, 对应孩子编码有重复, 故使用多对一匹配
3. drop if _merge == 2
4. drop _merge
5. }
其次,使用 pid 作为匹配变量,对个人库进行匹配。从结果来看,有 37354 个样本匹配成功,这与官方提供的数据清理报告显示的个人库样本量完全一致。其余样本未匹配成功主要是因为家庭成员库包含了所有的受访者,而个人库只包含了 10 岁及以上的受访者。
. merge 1:1 pid using cfps2018person_202012, force //匹配个人库
Result Number of obs
-----------------------------------------
Not matched 21,150
from master 21,150 (_merge==1)
from using 0 (_merge==2)
Matched 37,354 (_merge==3)
-----------------------------------------
最后,删除年龄在 18 岁以下的样本,即得到成人与少儿代答匹配的数据。
. drop if age < 18
5. 变量计算
接下来,围绕子女数量计算一些在未来研究中可能会用到的变量。
子女数量:家庭成员库提供了个体对应的每个子女 (如果有子女) 的样本编码,如变量 pid_a_c1 表示第 1 个子女的样本编码。若该变量有对应的编码,则表示个体有第 1 个孩子,若该变量取值 -8 (不适用) 或 77,则表示个体没有第 1 个孩子。据此,可通过如下代码计算每个受访者的子女数量。
. * 成年个体的子女数量
. forvalues i = 1(1)10{
2. gen xx`i' = 0 if pid_a_c`i' == -8 | pid_a_c`i' == 77 //若不存在, 则 x`i' = 0
3. replace xx`i' = 1 if pid_a_c`i' != -8 & pid_a_c`i' != 77 //若存在, 则 x`i' = 1
4. }
. egen childnumber = rowtotal(xx*) //子女数量, childnumber = 0 表示没有子女
子女中男孩和女孩数量:家庭成员库提供了每个子女的性别,如变量 tb2_a_c1 表示个体的第 1 个孩子的性别,取值 1 表示第 1 个孩子是男孩,取值 0 表示第 1 个孩子是女孩。据此,我们可以根据该变量来计算男孩和女孩的数量。
. * 分性别计算子女数量
. egen malechildnumber = anycount(tb2_a_c*), v(1) //男孩数量
. egen femalechildnumber = anycount(tb2_a_c*), v(0) //女孩数量
成年子女和未成年子女数量:家庭成员库提供了每个子女的出生年份变量,如 tb1y_a_c1 表示第 1 个子女的出生年份。此处主要是根据每个子女的出生年份来进行计算,具体代码如下:
. * 计算成年子女和未成年子女数量
. forvalues i = 1(1)10{
2. replace tb1y_a_c`i' = . if tb1y_a_c`i' <0 //将孩子 i 出生年份小于 0 的值处理成缺失值
3. gen tb1y_a_c`i'`i' = 2018 - tb1y_a_c`i' //计算子女 i 年龄
4. gen adult`i' = 1 if tb1y_a_c`i'`i' >17 & tb1y_a_c`i'`i'!=.
. //adult`i' = 1 表示第 i 个子女的年龄大于 17 岁, 成年人
5. replace adult`i' = 0 if tb1y_a_c`i'`i' <18 &tb1y_a_c`i'`i'!=.
. //adult`i' = 0 表示第 i 个子女的年龄小于 18 岁, 未成年
6. gen maleadultchild`i' = 1 if tb1y_a_c`i'`i' >17 & tb2_a_c`i' ==1
7. //maleadultchild`i' = 1 表示第 i 个子女为男性成年子女
. }
. egen adultchildnumber = anycount(adult*), v(1) //成年子女数量
. egen unadultchildnumber = anycount(adult*), v(0) //未成年子女数量
成年子女中男性与女性的数量:先根据出生年份和性别计算成年子女中男性的数量,再用成年子女数量减去男性数量,即可得到成年子女中女性数量。
. * 成年子女中男性与女性的数量
. egen maleadultchildnumber = anycount(maleadultchild*), v(1) //成年子女中男性的数量
. gen femaleaultchildnumber = adultchildnumber - maleadultchildnumber //成年子女中女性的数量
0-3 岁子女数量:主要根据出生年份和性别计算。
. forvalues i = 1(1)10{
2. replace tb1y_a_c`i' = . if tb1y_a_c`i' < 0 //将出生年份小于 0 的值处理成缺失值
3. gen child0_3`i' = 1 if tb1y_a_c`i'`i' > 3 & tb1y_a_c`i'`i' !=. //adult`i'=1 表示第 i 个子女的年龄大于 3 岁
4. replace child0_3`i' = 0 if tb1y_a_c`i'`i' < 4 & tb1y_a_c`i'`i' !=. //adult`i'=0 表示第 i 个子女的年龄小于4岁
5. }
. egen childnumber_0_3 = anycount(child0_3*),v(0) //0-3岁子女数量
需要说明的是,由于部分变量取值缺失等原因,不同计算口径下的结果可能并不一致。例如,若数据库中报告了每个子女的 ID 信息,但部分子女的性别信息有缺失,那么根据子女 ID 信息计算的子女数量与根据子女性别计算出的子女数量会有所差异。因此,建议尽量采用统一标准计算,但思路可参考本文。
6. 相关推文
Note:产生如下推文列表的 Stata 命令为:
lianxh cfps 合并 egen, m
安装最新版lianxh
命令:
ssc install lianxh, replace
专题:数据分享 清洗CFPS:两步搞定中国家庭追踪调查数据清洗 Stata数据处理:清洗CFPS数据库 专题:Stata入门 Stata小白系列之二:数据拆分与合并 专题:Stata教程 Stata小白系列之二:数据拆分与合并 专题:Stata命令 Stata新命令:ereplace-egenmore-egenmisc 专题:数据处理 Stata数据处理:快速合并与编码-encodefrom Stata 数据标签和合并 Stata:数据合并与匹配-merge-reclink multimport : 一次性导入并合并多个文件 Stata: 如何快速合并 3500 个无规则命名的数据文件? Stata:gen 和 egen 中的 sum() 函数异同
New! Stata 搜索神器:
lianxh
和songbl
GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉 使用:
. lianxh DID 倍分法
. songbl all
🍏 关于我们
连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。 直通车: 👉【**百度一下:**连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。