搜索
人大经济论坛 附件下载

附件下载

所在主题:
文件名:  sample.rar
资料下载链接地址: https://bbs.pinggu.org/a-1320984.html
本附件包括:
  • sample.dta
附件大小:
有如下格式数据:
id date B E MA Var1 Var2 Var3
AA 1980/01/02 1 . .
B 1980/01/31 0 . .
C 1982/02/16 . . 1
D 1982/03/18 . 0 .
AA 1982/03/21 . 1 .
AA 1982/03/21 1 . .
B 1982/03/22
AA 1983/06/30 . 0 .
E 1985/11/22 0 . .
AA 1985/12/31 0 . .
G 1987/01/01 . . 1
D 1991/02/27 . 1 .
.
AA 1999/03/16 . . 1
.
Z 2010/12/31 0 . .


想在Var1列生成本行对应id过去5年在B=1的情况下重复出现的次数(不计当次),在Var2列生成本行对应id过去5年在E=1的情况下重复出现的次数(不计当次),在Var3列生成本行对应id过去5年在MA=1的情况下重复出现的次数(不计当次)。举例来说,对应AA 1985/12/31行,Var1应显示1,Var2应显示1,Var3应显示0

我根据以前dxystata在类似问题中的程序,改写程序如下:
gen Var1=.
local N = _N
forvalues i = 1/`N' {
count if B==1&id==id[`i'] & (date[`i']-date)/365.2<=5 & (date[`i']-date)/365.2>0
replace var1=r(N) in `i'
}
但是这个程序运算速度比较慢,遇到观察值为几十万的情况,几个小时也出不了结果。

哪位高人有比较好的解决办法啊?非常感谢!!!

根据jonathanjp引用Nick Cox的建议,我编写如下代码,优点是不需要任何循环,因此速度快,缺点是如果数据量比较大,例如我提供的样本,会占用大量内存,甚至超过32G。
bys id Date: egen total_B=total(B)
bys id Date: egen total_E=total(E)
bys id Date: egen total_MA=total(MA)
duplicates drop id Date, force
egen ID=group(id)
xtset ID Date
tsfill
bys ID (Date): gen sum_B=sum(total_B)
bys ID (Date): gen freq_B=l.sum_B-l1827.sum_B
bys ID (Date): gen sum_E=sum(total_E)
bys ID (Date): gen freq_E=l.sum_E-l1827.sum_E
bys ID (Date): gen sum_MA=sum(total_MA)
bys ID (Date): gen freq_MA=l.sum_MA-l1827.sum_MA
drop if missing(id)

根据jonathanjp引用Michael Barker的程序,我进行了试验,运行速度也不快,而且结果有问题,但是思路有帮助。我一开始写的那个程序把每一个obs和其他所有obs进行比较,比较是否id一致及是否在5年之内,这样在样本大的情况下,运行速度自然很慢。现在有没有可能在一开始按时间sort数据的情况下,循环程序截止在5年的时间范围内?

目前为止,不管使用循环还是不使用循环,如果想解决速度问题,voodoo提出的“分而治之”的思路是最佳方案。

我把voodoo的“分而治之”的方法评为最佳答案,这个方法唯一的缺点是需要写的程序较为复杂,但是这种“分而治之”的思路是很好用的,而且程序运行速度比较快,不过多耗费系统资源。我写的上面这个不需要循环的程序运行速度最快而且代码比较简洁,但是必须保证内存足够大(建议16G或以上)。







    熟悉论坛请点击新手指南
下载说明
1、论坛支持迅雷和网际快车等p2p多线程软件下载,请在上面选择下载通道单击右健下载即可。
2、论坛会定期自动批量更新下载地址,所以请不要浪费时间盗链论坛资源,盗链地址会很快失效。
3、本站为非盈利性质的学术交流网站,鼓励和保护原创作品,拒绝未经版权人许可的上传行为。本站如接到版权人发出的合格侵权通知,将积极的采取必要措施;同时,本站也将在技术手段和能力范围内,履行版权保护的注意义务。
(如有侵权,欢迎举报)
二维码

扫码加我 拉你入群

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

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

GMT+8, 2026-1-1 07:01