Stata:模糊匹配-matchit-reclink
👇 连享会 · 推文导航 | www.lianxh.cn
🍎 Stata:Stata基础 | Stata绘图 | Stata程序 | Stata新命令 📘 论文:数据处理 | 结果输出 | 论文写作 | 数据分享 💹 计量:回归分析 | 交乘项-调节 | IV-GMM | 时间序列 | 面板数据 | 空间计量 | Probit-Logit | 分位数回归 ⛳ 专题:SFA-DEA | 生存分析 | 爬虫 | 机器学习 | 文本分析 🔃 因果:DID | RDD | 因果推断 | 合成控制法 | PSM-Matching 🔨 工具:工具软件 | Markdown | Python-R-Stata 🎧 课程:公开课-直播 | 计量专题 | 关于连享会
连享会寒假班
涂漫漫(中山大学)
邮箱:tumm@mail2.sysu.edu.cn
目录
1. 引言
1. `matchit` 命令
1.1 命令简介
1.2 实例:使用 `matchit` 命令匹配两个数据集中的公司名称
2. `reclink` 命令
2.1 命令简介
2.2 实例:使用 `reclink` 命令匹配两个数据集中的公司名称
3. 总结
4. 参考资料
5. 相关推文
温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:
1. 引言
关于匹配,我们最常用的匹配命令为 merge
,详见 help merge
,该命令可以匹配一个或多个关键变量,还可以进行 1:1 、1:m 、m:1 以及 m:m 操作,匹配成功的样本关键变量所含的数据是完全相同的。
但在现实操作中,我们经常会遇到需要合并的变量在两个数据集中并没有完美的联系,这时候就需要用到模糊匹配。
比如我们想按照人名或者学校名或者公司名进行匹配,然而同一个人/学校/公司常常有相似却不完全相同的名称,这种情况尤其常见。例如,一个数据集中人名为 "F.Hernandez" ,而另一个数据集中是 "Flor Hernandez" ;一个是 "普林斯顿小学" ,另一个是 "普林斯顿Elem" ;或者按照公司名匹配时出现 "平安保险(集团)股份有限公司" 或 "国平安保险股份有限公司" ,其实两者代表的是同一个公司,但是在 merge
的精确匹配下是无法匹配成功的,因此 “模糊匹配” 应运而生。根据模糊匹配的命令检查两个字符串是否匹配时会按照一系列标准进行匹配,如不那么严格的递增匹配需求,迭代地创建和删除匹配等。在允许某些字母变化的情况下,此命令创建一个变量,跟踪有多少变量在变化。
本文将介绍 Stata 自带的 matchit
以及 reclink
两个模糊匹配命令。为了方便展示这两个命令匹配的效果,本文挑选使用了部分公司名称数据进行匹配。数据集A为母公司代码-年份-子公司名称-子公司地址,数据集B为母公司代码-年份-子公司名称-子公司收入,现使用模糊匹配方法将两份数据按照子公司名称匹配。
1. matchit
命令
matchit
通过执行许多不同的基于字符串的匹配技术,在两个不同的文本字符串之间提供相似性评分。该命令会返回一个新的匹配程度变量( similscore ),其中包含从 0 到 1 的相似性评分。根据所选择的字符串匹配技术,similscore 为 1 意味着完全相似,当匹配不太相似时,相似度会降低。匹配程度是一个相对的度量,它可以(而且经常)根据所选择的技术而改变。有关这些技术的更多信息,请参阅 Raffo, J., & Lhuillery, S. (2009)
1.1 命令简介
*- 同一数据集中两列中的数据
matchit varname1 varname2 [, options]
*- 两个不同数据集中的数据
matchit idmaster txtmaster using filename.dta , idusing (varname) txtusing(varname) [options]
这里主要讲解如何模糊匹配两个不同数据集中的数据。其中,idmaster
指的是来自当前文件(主文件)的数值型变量名。txtmaster
指的是当前文件(主文件)中要进行匹配的字符型变量名。(注:idmaster
应该唯一识别 txtmaster
,即两者传达的是同一信息)。idusing(varname)
与 txtusing(varname)
同理,分别指来自于filename.dta数据集中待匹配的数值型变量以及字符型变量。具体内容可参见 Stata 的 help 文件:help matchit
。
1.2 实例:使用 matchit
命令匹配两个数据集中的公司名称
注意:matchit
在计算权重时需要安装 freqindex
命令如下:
*-安装命令
. ssc install freqindex, replace
. ssc install matchit, replace
*-先大致看一下两个数据集中公司名称
· use sample A.dta
· gen IDmaster = _n
· list in 1/20
| IDmaster stkcd year sub_nameA pro |
|---------------------------------------------------------------|
1. | 1 2 2007 万科中粮(苏州)置业有限公司 江苏 |
2. | 2 2 2007 万轩置业(深圳)有限公司 广东 |
3. | 3 2 2007 上海万科中实房地产有限公司 上海 |
4. | 4 2 2007 上海万科兰乔置业有限公司 上海 |
5. | 5 2 2007 上海万科宝北置业有限公司 上海 |
|---------------------------------------------------------------|
6. | 6 2 2007 上海万科宝南置业有限公司 上海 |
7. | 7 2 2007 上海万科宝山置业有限公司 上海 |
8. | 8 2 2007 上海万科徐汇置业有限公司 上海 |
9. | 9 2 2007 上海万科恒大房产股份有限公司 上海 |
10. | 10 2 2007 上海万科房地产有限公司 上海 |
|---------------------------------------------------------------|
11. | 11 2 2008 万科(重庆)房地产有限公司 重庆 |
12. | 12 2 2008 万科中粮(苏州)置业有限公司 江苏 |
13. | 13 2 2008 万轩置业(深圳)有限公司 广东 |
14. | 14 2 2008 上海万科中实房地产有限公司 上海 |
15. | 15 2 2008 上海万科宝北置业有限公司 上海 |
|---------------------------------------------------------------|
16. | 16 2 2008 上海万科宝南置业有限公司 上海 |
17. | 17 2 2008 上海万科宝山置业有限公司 上海 |
18. | 18 2 2008 上海万科徐汇置业有限公司 上海 |
19. | 19 2 2008 上海万科房地产有限公司 上海 |
20. | 20 2 2008 上海万科投资管理有限公司 上海 |
· use sampleB.dta
· gen IDusing = _n
· list in 1/20
| IDusing stkcd year Sub_nameB rev |
|---------------------------------------------------------------|
1. | 1 2 2007 万科中粮(苏州)置业有限公司 .1114724 |
2. | 2 2 2007 深圳市万轩置业有限公司 .3570185 |
3. | 3 2 2007 上海万科中实房地产有限公司 .5967776 |
4. | 4 2 2007 上海万科兰乔置业有限公司 .5308321 |
5. | 5 2 2007 上海万科宝北置业有限公司 .0658076 |
|----------------------------------------------------------------|
6. | 6 2 2008 万科(重庆)企业有限公司 .3257499 |
7. | 7 2 2008 万科中粮(苏州)置业有限公司 .9919564 |
8. | 8 2 2008 深圳市万轩置业有限公司 .7282419 |
9. | 9 2 2008 上海万科中实房地产有限公司 .0458555 |
10. | 10 2 2008 上海万科宝北置业有限公司 .0528195 |
|----------------------------------------------------------------|
11. | 11 2 2009 万科(重庆)企业有限公司 .558228 |
12. | 12 2 2009 万科中粮(苏州)置业有限公司 .2491597 |
13. | 13 2 2009 上海万科宝北置业有限公司 .3560052 |
14. | 14 2 2009 上海万科长宁置业有限公司 .6431996 |
15. | 15 2 2009 上海万科投资管理有限公司 .7743662 |
|----------------------------------------------------------------|
16. | 16 2 2010 万科(重庆)企业有限公司 .3291632 |
17. | 17 2 2010 万科中粮(苏州)置业有限公司 .6685566 |
18. | 18 2 2010 上海万科宝北置业有限公司 .4827962 |
19. | 19 2 2010 上海万科长宁置业有限公司 .8484485 |
20. | 20 2 2010 上海万科投资管理有限公司 .5178186 |
*-按照sub_name(子公司名称)模糊匹配
. use sample A.dta, replace
· matchit IDmaster sub_nameA using sampleB.dta , idusing (IDusing) txtusing(Sub_nameB)
注意:matchit
匹配结束后,只会保存sampleA&B的 ID 、子公司名称 以及 sampleA&B 按照公司名称匹配的得分(similscore)
gsort IDmaster sub_nameA -similscore
preserve
bys IDmaster: gen x = _n
keep if x <= 5
drop x
list in 1/20
restore
*- 结果呈现如下:
| IDmaster sub_nameA IDusing Sub_nameB similsc~e |
|--------------------------------------------------------------------------------------------|
1. | 1 万科中粮(苏州)置业有限公司 1 万科中粮(苏州)置业有限公司 .84963489 |
2. | 1 万科中粮(苏州)置业有限公司 17 万科中粮(苏州)置业有限公司 .84963489 |
3. | 1 万科中粮(苏州)置业有限公司 7 万科中粮(苏州)置业有限公司 .84963489 |
4. | 1 万科中粮(苏州)置业有限公司 12 万科中粮(苏州)置业有限公司 .84963489 |
5. | 1 万科中粮(苏州)置业有限公司 4 上海万科兰乔置业有限公司 .69767442 |
|--------------------------------------------------------------------------------------------|
6. | 2 万轩置业(深圳)有限公司 8 深圳市万轩置业有限公司 .86576808 |
7. | 2 万轩置业(深圳)有限公司 2 深圳市万轩置业有限公司 .86576808 |
8. | 2 万轩置业(深圳)有限公司 537 长沙深业置业有限公司 .66666667 |
9. | 2 万轩置业(深圳)有限公司 534 长沙深业置业有限公司 .66666667 |
10. | 2 万轩置业(深圳)有限公司 540 长沙深业置业有限公司 .66666667 |
|--------------------------------------------------------------------------------------------|
11. | 3 上海万科中实房地产有限公司 3 上海万科中实房地产有限公司 1 |
12. | 3 上海万科中实房地产有限公司 9 上海万科中实房地产有限公司 1 |
13. | 3 上海万科中实房地产有限公司 19 上海万科长宁置业有限公司 .72986649 |
14. | 3 上海万科中实房地产有限公司 14 上海万科长宁置业有限公司 .72986649 |
15. | 3 上海万科中实房地产有限公司 963 上海丰扬房地产开发有限公司 .72112526 |
|--------------------------------------------------------------------------------------------|
16. | 4 上海万科兰乔置业有限公司 4 上海万科兰乔置业有限公司 1 |
17. | 4 上海万科兰乔置业有限公司 18 上海万科宝北置业有限公司 .85738591 |
18. | 4 上海万科兰乔置业有限公司 10 上海万科宝北置业有限公司 .85738591 |
19. | 4 上海万科兰乔置业有限公司 13 上海万科宝北置业有限公司 .85738591 |
20. | 4 上海万科兰乔置业有限公司 5 上海万科宝北置业有限公司 .85738591 |
根据匹配结果可以看出,matchit
命令为 master data 里的子公司名称分别匹配若干个来自 using data 名称相似的子公司,匹配得分(similscore)越高,子公司名称的相似度越高。此时,我们只需要保存similscore得分最高的匹配样本并手工检查即可。但需要注意的是,matchit 是遍历using sample里所有子公司名称,并保留similscore大于等于0.5的匹配样本,因此存在不隶属于同一个母公司下子公司被成功匹配的情形,这就需要我们手工检查匹配结果。
2. reclink
命令
reclink
本质上也是一种模糊匹配方法。在无法精确匹配关键字段的两个数据集之间,reclink
使用记录链接方法来匹配观察结果。
2.1 命令简介
reclink varlist using filename , idmaster(varname) idusing(varname) gen(newvarname) [ wmatch(match weight list) wnomatch(non-match weight list) orblock(varlist) required(varlist) exactstr(varlist) exclude(filename) _merge(newvarname) uvarlist(varlist) uprefix(text) minscore(#) minbigram(#)
*-常用的命令形式如下:
reclink varlist using filename , idmaster(varname) idusing(varname) gen(newvarname) [required(varlist)]
reclink varlist
中的 varlist
指的是待匹配的一系列变量名称,idmaster(varname)
指定主数据集中唯一标识观测值的变量的名称,idusing(varname)
与 idmaster
类似,指的是 filename 中唯一标识观测值的变量的名称,gen(newvarname)
则是创建的一个新变量的名称,该变量用于存储匹配值之间的匹配分数(范围为0-1)。required(varlist)
为可选择的命令,其允许用户指定一个或多个必须完全匹配的变量,这样观察才能被视为匹配。具体内容可参见 Stata 的 help 文件:help reclink
。
2.2 实例:使用 reclink
命令匹配两个数据集中的公司名称
这里用到的两个数据集与实例 1 一致,仍然是 Sample A 为母公司代码-年份-子公司名称-子公司地址,Sample B 为母公司代码-年份-子公司名称-子公司收入。需要注意的是,我们想要实现:归属于同一个母公司的两个子公司才能模糊匹配。
*-安装命令
. ssc install freqindex, replace
. ssc install reclink, replace
*-先大致看一下两个数据集中公司名称
· use sample A.dta
· gen IDmaster = _n
· list in 1/20
| IDmaster stkcd year Sub_name pro |
|---------------------------------------------------------------|
1. | 1 2 2007 万科中粮(苏州)置业有限公司 江苏 |
2. | 2 2 2007 万轩置业(深圳)有限公司 广东 |
3. | 3 2 2007 上海万科中实房地产有限公司 上海 |
4. | 4 2 2007 上海万科兰乔置业有限公司 上海 |
5. | 5 2 2007 上海万科宝北置业有限公司 上海 |
|---------------------------------------------------------------|
6. | 6 2 2007 上海万科宝南置业有限公司 上海 |
7. | 7 2 2007 上海万科宝山置业有限公司 上海 |
8. | 8 2 2007 上海万科徐汇置业有限公司 上海 |
9. | 9 2 2007 上海万科恒大房产股份有限公司 上海 |
10. | 10 2 2007 上海万科房地产有限公司 上海 |
|---------------------------------------------------------------|
11. | 11 2 2008 万科(重庆)房地产有限公司 重庆 |
12. | 12 2 2008 万科中粮(苏州)置业有限公司 江苏 |
13. | 13 2 2008 万轩置业(深圳)有限公司 广东 |
14. | 14 2 2008 上海万科中实房地产有限公司 上海 |
15. | 15 2 2008 上海万科宝北置业有限公司 上海 |
|---------------------------------------------------------------|
16. | 16 2 2008 上海万科宝南置业有限公司 上海 |
17. | 17 2 2008 上海万科宝山置业有限公司 上海 |
18. | 18 2 2008 上海万科徐汇置业有限公司 上海 |
19. | 19 2 2008 上海万科房地产有限公司 上海 |
20. | 20 2 2008 上海万科投资管理有限公司 上海 |
· use sampleB.dta
· gen IDusing = _n
· list in 1/20
| IDusing stkcd year Sub_name rev |
|------------------------------------------------------------------|
1. | 1 2 2007 万科中粮(苏州)置业有限公司 .1114724 |
2. | 2 2 2007 深圳市万轩置业有限公司 .3570185 |
3. | 3 2 2007 上海万科中实房地产有限公司 .5967776 |
4. | 4 2 2007 上海万科兰乔置业有限公司 .5308321 |
5. | 5 2 2007 上海万科宝北置业有限公司 .0658076 |
|------------------------------------------------------------------|
6. | 6 2 2008 万科(重庆)企业有限公司 .3257499 |
7. | 7 2 2008 万科中粮(苏州)置业有限公司 .9919564 |
8. | 8 2 2008 深圳市万轩置业有限公司 .7282419 |
9. | 9 2 2008 上海万科中实房地产有限公司 .0458555 |
10. | 10 2 2008 上海万科宝北置业有限公司 .0528195 |
|------------------------------------------------------------------|
11. | 11 2 2009 万科(重庆)企业有限公司 .558228 |
12. | 12 2 2009 万科中粮(苏州)置业有限公司 .2491597 |
13. | 13 2 2009 上海万科宝北置业有限公司 .3560052 |
14. | 14 2 2009 上海万科长宁置业有限公司 .6431996 |
15. | 15 2 2009 上海万科投资管理有限公司 .7743662 |
|------------------------------------------------------------------|
16. | 16 2 2010 万科(重庆)企业有限公司 .3291632 |
17. | 17 2 2010 万科中粮(苏州)置业有限公司 .6685566 |
18. | 18 2 2010 上海万科宝北置业有限公司 .4827962 |
19. | 19 2 2010 上海万科长宁置业有限公司 .8484485 |
20. | 20 2 2010 上海万科投资管理有限公司 .5178186 |
*-按照sub_name(子公司名称)模糊匹配,同时要求stkcd year精确匹配
. use sample A.dta, replace
· reclink stkcd year Sub_name using sampleB.dta , idmaster(IDmaster) idusing(IDusing) gen(Score) required(stkcd year)
注意:reclink
匹配结束后,会保留两个数据集的所有变量名称,这也是 reclink
优于 matchit
的表现之一。
gsort IDmaster sub_name -Score
preserve
bys IDmaster: gen x = _n
keep if x <= 5
drop x
list in 1/20
restore
*- 结果呈现如下:
| IDmaster stkcd Ustkcd year Uyear Sub_name USub_name pro Score IDusing rev _merge |
|------------------------------------------------------------------------------------------------------------------------------------------------------|
1. | 1 2 2 2007 2007 万科中粮(苏州)置业有限公司 万科中粮(苏州)置业有限公司 江苏 0.9970 1 .1114724 3 |
2. | 2 2 2 2007 2007 万轩置业(深圳)有限公司 深圳市万轩置业有限公司 广东 0.9928 2 .3570185 3 |
3. | 3 2 2 2007 2007 上海万科中实房地产有限公司 上海万科中实房地产有限公司 上海 1.0000 3 .5967776 3 |
4. | 4 2 2 2007 2007 上海万科兰乔置业有限公司 上海万科兰乔置业有限公司 上海 1.0000 4 .5308321 3 |
5. | 5 2 2 2007 2007 上海万科宝北置业有限公司 上海万科宝北置业有限公司 上海 1.0000 5 .0658076 3 |
|------------------------------------------------------------------------------------------------------------------------------------------------------|
6. | 6 2 2 2007 2007 上海万科宝南置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9621 1 .1114724 3 |
7. | 7 2 2 2007 2007 上海万科宝山置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9621 1 .1114724 3 |
8. | 8 2 2 2007 2007 上海万科徐汇置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9673 1 .1114724 3 |
9. | 9 2 2 2007 2007 上海万科恒大房产股份有限公司 万科中粮(苏州)置业有限公司 上海 0.7491 1 .1114724 3 |
10. | 10 2 2 2007 2007 上海万科房地产有限公司 万科中粮(苏州)置业有限公司 上海 0.7630 1 .1114724 3 |
|------------------------------------------------------------------------------------------------------------------------------------------------------|
11. | 11 2 2 2008 2008 万科(重庆)房地产有限公司 万科(重庆)企业有限公司 重庆 0.9797 6 .3257499 3 |
12. | 12 2 2 2008 2008 万科中粮(苏州)置业有限公司 万科中粮(苏州)置业有限公司 江苏 0.9970 7 .9919564 3 |
13. | 13 2 2 2008 2008 万轩置业(深圳)有限公司 深圳市万轩置业有限公司 广东 0.9928 8 .7282419 3 |
14. | 14 2 2 2008 2008 上海万科中实房地产有限公司 上海万科中实房地产有限公司 上海 1.0000 9 .0458555 3 |
15. | 15 2 2 2008 2008 上海万科宝北置业有限公司 上海万科宝北置业有限公司 上海 1.0000 10 .0528195 3 |
|------------------------------------------------------------------------------------------------------------------------------------------------------|
16. | 16 2 2 2008 2008 上海万科宝南置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9621 7 .9919564 3 |
17. | 17 2 2 2008 2008 上海万科宝山置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9621 7 .9919564 3 |
18. | 18 2 2 2008 2008 上海万科徐汇置业有限公司 万科中粮(苏州)置业有限公司 上海 0.9673 7 .9919564 3 |
19. | 19 2 2 2008 2008 上海万科房地产有限公司 万科(重庆)企业有限公司 上海 0.9369 6 .3257499 3 |
20. | 20 2 2 2008 2008 上海万科投资管理有限公司 万科(重庆)企业有限公司 上海 0.7688 6 .3257499 3 |
匹配结果可见,只有stkcd year唯一匹配后,子公司名称才能模糊匹配。即该命令能够为 master data 里的子公司名称匹配来自于 using data 里相同母公司( stkcd )相同年份( year )中的子公司。匹配得分( similscore )越高,子公司名称的相似度越高。此时,我们只需要保存 similscore 得分最高的匹配样本并手工检查即可。
3. 总结
本文介绍了 matchit
以及 reclink
两种模糊匹配的命令,前者可以实现同一个数据集两个不同变量的匹配得分以及两个不同数据集变量的模糊匹配,后者则可以实现指定一个或多个必须完全匹配的变量,再设置需要模糊匹配的变量。在具体执行过程中,可按照研究需求灵活选择匹配命令。
4. 参考资料
Raffo J, Lhuillery S. How to play the “Names Game”: Patent retrieval comparing different heuristics[J]. Research policy, 2009, 38(10): 1617-1627. -PDF- Raffo - 2016, Data consolidation and cleaning using fuzzy string comparisons with -matchit- command, 2016 Swiss Stata Users Group meeting. -PDF-
5. 相关推文
Note:产生如下推文列表的 Stata 命令为:
lianxh 匹配 倾向,m
安装最新版lianxh
命令:
ssc install lianxh, replace
专题:数据处理 Stata:数据合并与匹配-merge-reclink 专题:倍分法DID 面板PSM+DID如何做匹配? 专题:PSM-Matching Stata-Matching:肾脏交换匹配问题 Stata:iematch-近邻贪婪匹配 Stata:终极匹配 ultimatch Stata 手动:各类匹配方法大全 A——理论篇 Stata:psestimate-倾向得分匹配(PSM)中协变量的筛选 Stata:广义精确匹配-Coarsened-Exact-Matching-(CEM) Stata:psestimate-倾向得分匹配(PSM)中匹配变量的筛选 Stata+PSM:倾向得分匹配分析简介 Stata-从匹配到回归:精确匹配、模糊匹配和PSM Stata:PSM-倾向得分匹配分析的误区 Stata:模糊匹配之matchit
连享会:因果推断专题
New! Stata 搜索神器:
lianxh
和songbl
GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉 使用:
. lianxh DID 倍分法
. songbl all
🍏 关于我们
连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。 直通车: 👉【百度一下:连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。