在上市公司供应链研究中,我们通常需要将上市公司前5大供应商的名称与税调企业数据进行匹配。由于匹配时采用的是去除干扰词匹配方法,同一个供应商 ID(gysid)往往会得到多条候选匹配结果。如何从中保留”最合适”的一条,是数据清理中的关键一步。
其实之所以保留是担心误删了有用的结果,所以希望这个操作由大家自己完成。
本文介绍一套系统性的去重方法,按优先级从高到低依次筛选,最终确保每个供应商 ID 只对应一条税调企业记录。
数据来源 本教程涉及以下两份数据:
上市公司前5大供应商与税调匹配结果:2007~2020年上市公司前5大供应商与税调数据匹配结果.dta
税调基本信息:税调基本信息07_20.dta
两份数据以税调企业 ID(sdid)为连接键进行联结,得到包含供应商名称和税调企业名称的合并数据集。
去重思路 去重的核心逻辑是:在存在多条候选匹配的情况下,按照一套优先级规则,逐步淘汰”较差”的匹配,保留”更好”的匹配 。
每一步的操作结构如下:
gen temp1 = (条件)bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0
这种方式的好处是:只在有更好选择时才删除 ,不会误删”唯一匹配”的记录。
第0步:读入数据并合并 use "2007~2020年上市公司前5大供应商与税调数据匹配结果.dta" , clear ren 企业名称 企业名称_工商joinby sdid using 税调基本信息07_20.dtaorder 供应商名称 企业名称save rawdata, replace
去重步骤详解 第1步:优先保留名称完全一致的匹配 最高优先级:若供应商名称与税调企业名称 完全相同 ,则优先保留这类精确匹配。
gen temp1 = (供应商名称 == 企业名称)bysort gysid: egen maxtemp1 = max (temp1)order temp1 maxtemp1drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第2步:优先保留”集团对集团”的匹配 供应商名称与税调名称 都含”集团” 的匹配,优于一方含集团、另一方不含集团的情况。这避免了将集团总部与其下属子公司混淆匹配。
cap drop temp1 maxtemp1gen temp1 = (index (供应商名称, "集团" ) & index (企业名称, "集团" ))bysort gysid: egen maxtemp1 = max (temp1)order temp1 maxtemp1drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第3步:优先保留”双方均不含集团”的匹配 若双方都不是集团级企业,则直接匹配更合理,排除一方是集团、另一方不是集团的错误匹配。
cap drop temp1 maxtemp1gen temp1 = (!index (供应商名称, "集团" ) & !index (企业名称, "集团" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第4、5步:排除银行支行、分行层级匹配 银行的支行和分行是上级机构的下设分支,非独立法人主体。若同一 gysid 存在非支行/分行层级的匹配,则优先保留后者。
cap drop temp1 maxtemp1gen temp1 = (!index (供应商名称, "支行" ) & !index (企业名称, "支行" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0cap drop temp1 maxtemp1gen temp1 = (!index (供应商名称, "分行" ) & !index (企业名称, "分行" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0
第6步:排除加油站等末端机构匹配 针对中国石化等大型能源企业,其旗下有大量加油站、服务站等末端机构。通过排除含”站”字的匹配,将结果聚焦于总部或分公司层级。
cap drop temp1 maxtemp1gen temp1 = (!index (供应商名称, "站" ) & !index (企业名称, "站" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第7步:排除企业内部部门匹配 名称中含”部”字的通常是企业内部部门(如”销售部”),而非独立注册的法人主体,优先排除此类匹配。
cap drop temp1 maxtemp1gen temp1 = (!index (供应商名称, "部" ) & !index (企业名称, "部" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第8步:优先保留标准”公司”结构 名称形如”XX公司YY公司”通常是多级嵌套或异常命名格式,优先保留正常的单层”公司”结构。
cap drop temp1 maxtemp1gen temp1 = (!ustrregexm(供应商名称, "公司(.*)公司" ) & !ustrregexm(企业名称, "公司(.*)公司" ))bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0duplicates report gysid
第9步:清理不对称的嵌套公司结构 当供应商名称与税调名称在嵌套结构上不对称时,强制删除单侧含异常后缀的记录。涵盖的情形包括:公司、局、煤矿、中心、厂、部等。
cap drop tags duplicates tag gysid, gen(tags) gsort -tags gysid *- 供应商含"公司...公司" vs 企业不含(删除不对称项) drop if ustrregexm(供应商名称, "公司(.*)公司") & !ustrregexm(企业名称, "公司(.*)公司") drop if !ustrregexm(供应商名称, "公司(.*)公司") & ustrregexm(企业名称, "公司(.*)公司") *- 其他不对称情形:公司与局、煤矿、中心、厂、部 drop if ustrregexm(供应商名称, "公司(.*)局") & !ustrregexm(企业名称, "公司(.*)公司") drop if !ustrregexm(供应商名称, "公司(.*)局") & ustrregexm(企业名称, "公司(.*)公司") *- ... 以此类推,共覆盖 12 种不对称组合 ... *- 供应商以"公司"结尾,但企业名称不以"公司"结尾 drop if ustrregexm(供应商名称, "公司$") & !ustrregexm(企业名称, "公司$")
第10步:去掉”股份”后比较名称 “XX有限责任公司”与”XX股份有限公司”在工商注册中属于不同名称,但实为同一企业。去掉”股份”后若名称相同,优先保留这类匹配。
cap drop temp1 maxtemp1gen 企业名称2 = subinstr (企业名称, "股份" , "" , .)gen temp1 = (供应商名称 == 企业名称2)bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0duplicates report gysidcap drop 企业名称2
第11步:强制去重(gysid + 企业名称组合重复项) 同一供应商 ID 对应完全相同企业名称的记录超出1条时,直接强制保留1条。
duplicates drop gysid 企业名称, force duplicates report gysid
第12步:去掉”责任”后比较名称 类似第10步,”有限公司”与”有限责任公司”是同一企业的不同写法,去掉”责任”后若名称相同,优先保留这类匹配。
cap drop temp1 maxtemp1gen 企业名称2 = subinstr (企业名称, "责任" , "" , .)gen temp1 = (供应商名称 == 企业名称2)bysort gysid: egen maxtemp1 = max (temp1)drop if temp1 == 0 & maxtemp1 > 0cap drop 企业名称2
第13步:字符串编辑距离兜底 经过前述所有规则后仍存在重复的 gysid,使用 strdist 命令计算字符串相似度 ,保留每组中相似度最高的匹配。
注意 :需提前安装 strdist 包:ssc install strdist
cap drop tagsduplicates tag gysid, gen (tags)tab tagsstrdist 供应商名称 企业名称 if tags > 0, gen (dist) bysort gysid: egen maxdist = max (dist)keep if dist == maxdist | mi (dist)duplicates report gysid
第14步:最终去重与输出 *- 每个 gysid 只保留1条记录 duplicates drop gysid, force *- 删除所有辅助变量 drop dist maxdist temp1 maxtemp1 tags *- 保存最终结果 save 2007~2020年上市公司前5大供应商与税调数据匹配结果(去除gysid重复).dta, replace
去重规则总结 下表汇总了本方法的 14 个去重步骤及其背后的逻辑:
步骤
优先保留的匹配类型
核心逻辑
1
名称完全一致
精确匹配优于模糊匹配
2
集团对集团
层级一致优于层级错位
3
双方均非集团
层级一致优于层级错位
4
双方均非支行
法人主体优于下设分支
5
双方均非分行
法人主体优于下设分支
6
双方均非”站”
总部/分公司优于末端机构
7
双方均非”部”
法人主体优于内部部门
8
双方均为标准公司
正常命名优于嵌套格式
9
结构对称
后缀类型需两侧一致
10
去”股份”后名称一致
同企业不同注册形式
11
强制去重(同名)
消除完全重复记录
12
去”责任”后名称一致
同企业不同注册形式
13
字符串相似度最高
兜底规则,量化相似度
14
最终强制去重
确保结果唯一
对于其他数据可能还存在其他类型的情况,可以再采用类似的方法去重。
关联课程 数据匹配与去重方法在供应链、企业关系等研究中非常常见,以下课程介绍了相关的数据匹配方法:
如何匹配中国工业企业数据库和海关数据库?以 2013 年为例:https://rstata.duanshu.com/#/course/5463b8d7afcb438ca1e537fa76c1a45d
工企和污染数据是如何匹配的?使用 Stata 完成整个过程:https://rstata.duanshu.com/#/course/7325758d0ad9457790215455dbcbcb1a
点击这里跳转到 RStata 短书平台获取附件:如何去重上市公司前5大供应商与税调数据匹配结果?
评论