楼主: refound
34225 8

[stata资源分享] stata多对多数据合并 [推广有奖]

  • 0关注
  • 1粉丝

已卖:277份资源

硕士生

26%

还不是VIP/贵宾

-

威望
0
论坛币
6171 个
通用积分
48.2944
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
549 点
帖子
31
精华
0
在线时间
228 小时
注册时间
2018-11-6
最后登录
2025-9-13

楼主
refound 学生认证  发表于 2019-7-5 10:25:05 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

转载自微信公众号:爬虫俱乐部  《

多对多合并》

我们在数据处理时,经常需要对文件进行横向合并,我们知道merge 1:1 varlist using filename [, options]可以进行一对一合并;merge 1:m varlist using filename [, options]可以进行一对多合并;merge m:1 varlist using filename [, options]可以进行多对一合并,然而在使用merge m:m varlist using filename [, options]进行多对多合并是有问题的,那么问题在哪?如何解决?这篇推文将会给大家解释清楚。



小试牛刀

1.生成两个dta文件:

clear

input id str3 v1

1 "a"

1 "b"

1 "c"

1 "d"

1 "e"

end

save 1.dta, replace

clear

input id str3 v2

1 "d"

1 "e"

1 "f"

end

save 2.dta, replace

接着,我们将两个文件进行横向合并,可以看到,由于两个文件中id不是唯一识别的,属于多对多合并。我们想要得到的结果如下图所示:

2.直接用merge m:m横向合并数据

use 1.dta, clear

merge m:m id using 2.dta

drop _m

可以看到,直接使用merge m:m进行多对多合并时,第一,并不是1.dta的观测值分别对应2.dta的每一条观测值;第二,当某个文件的观测值少时,将会以该文件中的最后一条观测值对另一个文件中的观测值进行合并,如上图第4、5行。那么怎么得到我们想要的结果呢?

3.先扩展,再合并

整体思路是,把多对多合并变为一对多或多对一合并。首先,我们在1.dta中生成变量n,等于所在行行号,然后求出n的最大值,放在局部宏中,并保存为3.dta文件,程序如下:

use 1.dta, clear

bysort id: gen n = _n

sum n

local max = r(max)

save 3.dta, replace

结果如图所示:

这样,把id和n两个变量作为合并依据就变成唯一的了,可以看到,n最大值为5。接着在2.dta中,对数据进行扩充相应的倍数,即1.dta中变量n的最大值:

use 2.dta,clear

expand `max'

bysort id v2 : gen n = _n

sort n v2

结果如图所示:

扩充后的数据,id和n作为合并依据的话,每个都为3个,所以可以与3.dta进行多对一合并,程序和结果如下:

merge m:1 id n using 3.dta

order id v1

sort id v1 v2

drop n _m

结果如图所示:



实例演练

我们在做事件研究时,如果某个事件发生在上市公司停牌期间,我们往往需要把其剔除掉,那么首先,我们需要按照股票代码把事件列表和停复牌时间进行横向合并,由于同一个公司可能对应多个时间,也可能多次停牌,因此应该进行多对多合并,为了方便大家操作,我们手动生成一个事件列表:

clear

set more off

input Stkcd str15 date

000001 "2006-03-01"

000001 "2007-06-05"

000001 "2007-05-05"

000001 "2010-03-01"

000001 "2013-05-06"

000002 "2003-07-25"

000002 "2009-08-16"

000002 "2010-05-09"

end

save 事件列表,replace

我们截取Stkcd为000001和000002公司的停复牌日期,如下图所示:

其中,startdate为停牌日期,enddate为复牌日期,合并之后,如果date,即时间发生日在停复牌时间之间,就剔除掉。

接下来,横向合并两个文件,程序如下:

use 事件列表, clear

bysort Stkcd : gen n = _n

sum n

local max = r(max)

save 事件列表1,replace  

use停复牌,clear

expand `max'

bysort Stkcd startdate enddate : gen n = _n

merge m:1 Stkcd n using 事件列表1

keep if _m == 3

drop _m n

结果如图所示:

这样,每一个事件都对应所有的停复牌日期,接着将发生在停复牌的事件删除即可,程序如下:

gen date1 = date(date,"YMD")

gen num = 1 if date1 >= startdate & date1 <= enddate

keep Stkcd date num

duplicates drop

sort Stkcd date num

bysort Stkcd date :carryforward num,replace

drop if num == 1

drop num


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝


沙发
zhouershimei 发表于 2020-9-6 09:38:01
怎样同时打开两个文件呢?

藤椅
周苏木 发表于 2020-11-5 21:46:36
zhouershimei 发表于 2020-9-6 09:38
怎样同时打开两个文件呢?
不是打开保存后,就可以一个作为主数据库

板凳
jimo6357 发表于 2020-11-11 15:37:48
因为表格没有显示出来,我想去爬虫俱乐部的公众号中看,但是找不到这篇文章,请问你在哪里找的[cry]

报纸
僧究研 发表于 2020-11-11 21:23:43
jimo6357 发表于 2020-11-11 15:37
因为表格没有显示出来,我想去爬虫俱乐部的公众号中看,但是找不到这篇文章,请问你在哪里找的
同,有链接可以分享下[tongue]

地板
4559392771 发表于 2020-12-25 17:23:41
jimo6357 发表于 2020-11-11 15:37
因为表格没有显示出来,我想去爬虫俱乐部的公众号中看,但是找不到这篇文章,请问你在哪里找的
可以看这篇:
https://stata-club.github.io/stata_article/2017-11-29.html

7
徐笨笨 发表于 2022-3-1 15:15:04
这个是有意joinby的命令,但感觉这个匹配的不完全

8
徐笨笨 发表于 2022-3-1 15:15:45
徐笨笨 发表于 2022-3-1 15:15
这个是有意joinby的命令,但感觉这个匹配的不完全
感觉它省了很多其它数据

9
暖手宝 学生认证  发表于 2023-3-20 11:03:19
你好,请问我现在需要匹配产品编码,将每年多的产品编码同一匹配到1996年版本的,但是需要匹配年份的产品编码和1996年的产品编码的对应情况有一对一的、多对一的、一对多的还有多对多的,这种情况下我应该怎么做匹配呢

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2026-2-8 17:56