Stata:多对多合并-merge-joinby

发布时间:2023-07-28 阅读 2544

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:鞠瑶蕾 (吉林大学)
邮箱1045751085@qq.com

编者按:本文主要整理自下文,特此致谢!
Source:Mazrekaj D, Wursten J. Stata tip 142: joinby is the real merge m: m[J]. The Stata Journal, 2021, 21(4): 1065-1068. -PDF-


目录


1. 背景介绍

1.1 m:m 匹配的隐患

merge 命令是 Stata 最常用的命令之一,只要匹配变量在其中一个数据集中能发挥唯一识别的作用 (即合并 1:1、1:m 或 m:1 的情况),merge命令可以正常工作。

然而,当匹配变量在所有数据集中都包含重复项 (不能唯一识别) 时,Stata 会给出一个错误信息,说匹配变量不能唯一识别 master 数据集或 using 数据集中的观测值。

例如,在下面的 jobs.dta 文件中,我们发现有两个人,分别担任面包师和律师的职务。而两人的姓和名都包含在 names.dta 文件中。

* jobs.dta
     +-------------+
     | id      job |
     |-------------|
  1. |  1    baker |
  2. |  2   lawyer |
     +-------------+

* names.dta
     +-------------------------+
     | id   firstname   surname|
     |-------------------------|
  1. |  1       John     Smith |
  2. |  2       Jane     Smith |
     +-------------------------+

在 Stata 中合并这两个数据集非常简单:

. use "jobs", clear
. merge 1:1 id using "names", nogen

合并之后的结果显示,John Smith 是一名面包师,Jane Smith 是一名律师。

. list
     +----------------------------------+
     | id      job   firstname   surname |
     |----------------------------------|
  1. |  1    baker       John     Smith |
  2. |  2   lawyer       Jane     Smith |
     +----------------------------------+

如果我们想要添加关于两人子女的信息,事情就变得棘手了。John Smith 和 Jane Smith 有两个孩子,分别是 Ken Smith 和 Sue Smith。

* children.dta
     +--------------------------------+
     | childfirstname   surname   age |
     |--------------------------------|
  1. |      Ken          Smith     8  |
  2. |      Sue          Smith     6  |
     +--------------------------------+

通过 surname 变量,children.dta 文件可以和 names.dta 合并。然而,Smith 家庭由多名父母和多名孩子组成,这意味着我们需要进行多对多合并,即 m:m。但是,Stata 的 merge 命令不会将这两个孩子都匹配给父母!相反,merge m:m 的结果如下所示:

. merge m:m surname using "children", nogen
. list
     +----------------------------------------------------+
     | id    job  firstname  surname  childfirstname  age |
     |----------------------------------------------------|
  1. |  1  baker    John      Smith         Ken         8 |
  2. |  2 lawyer    Jane      Smith         Sue         6 |
     +----------------------------------------------------+

merge m:m 将第一位父母与第一个孩子匹配到一起,而将第二位父母与第二个孩子匹配到一起。最终的结果并不是如愿地将两个孩子都匹配给父母。 在这种情况下,Stata 将不会返回错误消息。

令人担忧的是,有些涉及多对多匹配的作者可能会在无意之中运行了 merge m:m,得到了有偏的合并结果,这与那些使用大型人口数据集的研究尤其相关。

1.2 joinby 命令

本推文将要介绍的新命令 joinby 能很好地处理这种情况。接下来,我们展示 joinby 命令的处理结果。

. drop childfirstname age
. joinby surname using "children"
. list
     +---------------------------------------------------+
     | id      job   firstn~e   surname   childf~e   age |
     |---------------------------------------------------|
  1. |  1    baker       John     Smith        Sue     6 |
  2. |  1    baker       John     Smith        Ken     8 |
  3. |  2   lawyer       Jane     Smith        Sue     6 |
  4. |  2   lawyer       Jane     Smith        Ken     8 |
     +---------------------------------------------------+

2. 实例说明

Stata 提供了 parent.dta 和 child.dta 两个数据集帮助我们展示 joinby 命令,以便于研究者理解和使用。

. webuse parent, clear
. list
     +--------------------------------+
     | family_id  parent_id  x1    x3 |
     |--------------------------------|
  1. |     1030      10      39   600 |
  2. |     1025      11      20   643 |
  3. |     1025      12      27   721 |
  4. |     1026      13      30   760 |
  5. |     1026      14      26   668 |
     |--------------------------------|

. webuse child, clear
. list
     +--------------------------------+
     | family_id   child_id  x1    x2 |
     |--------------------------------|
  1. |     1025        3     11   320 |
  2. |     1025        1     12   300 |
  3. |     1025        4     10   275 |
  4. |     1026        2     13   280 |
  5. |     1027        5     15   210 |
  6. |     1030         15   32   684 |
     +--------------------------------+

然后,我们通过 parent 和 child 两个数据集展示 joinby 的使用过程。

. webuse parent, clear
. joinby family_id using "https://www.stata-press.com/data/r17/child"
. sort family_id parent_id child_id

合并后的数据集正确地包含了家庭的组成情况。在默认情况下,joinby会自动排除不匹配的观测值。在本案例中,这意味着 parent_id=10、parent_id=15 和 child_id=5 不存在合并后的数据集中。这种默认情况可以通过 unmatched() 选项来改变。

. list, sepby(family_id)
     +---------------------------------------------------+
     | family_id   parent_id   x1    x3   child_id    x2 |
     |---------------------------------------------------|
  1. |     1025       11       20   643          1   300 |
  2. |     1025       11       20   643          3   320 |
  3. |     1025       11       20   643          4   275 |
  4. |     1025       12       27   721          1   300 |
  5. |     1025       12       27   721          3   320 |
  6. |     1025       12       27   721          4   275 |
  7. |     1026       13       30   760          2   280 |
  8. |     1026       14       26   668          2   280 |
     +---------------------------------------------------+

merge 相似,joinby 也提供了处理两个数据集中出现变量的 option。默认情况下,joinby 保留 master 数据集的值。update 选项会用 using 数据集的值填补缺失值,而 replace 选项会用 using 数据集的值覆盖 master 数据集的值,using 数据集的值缺失除外。

将此结果与 merge m:m 的结果进行对比,此时我们放入 keep(match) 来模拟 joinby 的默认情况 (排除不匹配的观测值)。

. webuse parent, clear
     +-------------------------------------------------+
     | family_id   parent_id   x1    x3   child_id    x2 |
     |---------------------------------------------------|
  1. |     1025       11       20   643          1   300 |
  2. |     1025       11       20   643          3   320 |
  3. |     1025       11       20   643          4   275 |
  4. |     1025       12       27   721          1   300 |
  5. |     1025       12       27   721          3   320 |
  6. |     1025       12       27   721          4   275 |
  7. |     1026       13       30   760          2   280 |
  8. |     1026       14       26   668          2   280 |
     +---------------------------------------------------+
. merge m:m family_id using ///
>     "https://www.stata-press.com/data/r17/child", ///
>     nogen keep
    Result                      Number of obs
    -----------------------------------------
    Not matched                             0
    Matched                                 5  
    -----------------------------------------
. sort family_id parent_id child_id

接下来的 merge m:m 结果非常危险,在第一个家庭 (id=1025) 中,它将第一个孩子 (id=3) 分配给第一个父母 (id=11),将所有剩余的孩子分配给第二个父母 (id=12)。

然而,在第二个家庭中,它又正确地将一个孩子 (id=2) 同时分配给父母双方 (id=13 和 id=14) 。因此,如果手动检查第二个家庭的匹配结果,研究者们会容易认为 merge m:m 完全符合研究设计要求,但此时它对不同家庭组成使用了不同的匹配规则。

. list, sepby(family_id)
     +-------------------------------------------------+
     | family_id   parent_id   x1    x3   child_id  x2 |
     |-------------------------------------------------|
  1. |     1025         11   20   643          3   320 |
  2. |     1025         12   27   721          1   300 |
  3. |     1025         12   27   721          4   275 |
     |-------------------------------------------------|
  4. |     1026         13   30   760          2   280 |
  5. |     1026         14   26   668          2   280 |
     +-------------------------------------------------+

3. 结语

上面的例子强调,当匹配变量不能唯一地识别 master 数据集和 using 数据集中的观测值时,研究者们要谨慎考虑 (甚至永远不能) 使用 merge m:m

相反,如果研究者想要将 using 数据集的所有观测值分配给 master 数据集中的所有观测值 (例如,将所有 child 数据分配给 parent 数据),那么 joinby 就可以实现这一点。

4. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 合并, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,400+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxh 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh