楼主: xingxf
7241 35

[编程问题求助] 生成过去特定一段时间特定条件下某ID重复出现的次数 [推广有奖]

21
xingxf 发表于 2013-5-2 22:34:35
voodoo 发表于 2013-5-2 21:51
那就从原程序中剔除#1步骤(仅保留save sample2, replace)。还是采用“分而治之”的方法,但将NSMPL设为 ...
您这个“分而治之”的方法还是挺可行的,但是就是程需要写得比较复杂。
我准备按照Dr Nick Cox的建议试一试,按那个思路可以不用循环。

22
voodoo 发表于 2013-5-2 22:41:50
xingxf 发表于 2013-5-2 22:34
您这个“分而治之”的方法还是挺可行的,但是就是程需要写得比较复杂。
我准备按照Dr Nick Cox的建议试一 ...
几乎是不可行的。你现在的sample.dta大小为11M,扩展后内存都装不下你数据!Nick Cox也提醒“Then the code would be  simpler,  but you would end up with several millions of observations”——我觉得恐怕不是millions,而是tens of million(>>530000*20)!
此外,code会变simpler吗?我没想到简单的思路。
巫毒上传,必属佳品!
坛友下载,三思后行!

23
xingxf 发表于 2013-5-2 23:00:11
voodoo 发表于 2013-5-2 22:41
几乎是不可行的。你现在的sample.dta大小为11M,扩展后内存都装不下你数据!Nick Cox也提醒“Then the co ...
stata12内存没问题,我32G内存应该跑的下。我经常处理几个G的数据,比如几千万行obs,没有问题的。
按照Nick的思路,在扩展之前,先要bys id date: egen E_sum=sum(E),然后duplicates drop,后面就可以把数据扩展为每日,然后设置xtset,利用tssmooth ma求移动平均值,得到结果再乘以5年的天数。
目前我是这个思路。

24
voodoo 发表于 2013-5-2 23:19:02
xingxf 发表于 2013-5-2 23:00
stata12内存没问题,我32G内存应该跑的下。我经常处理几个G的数据,比如几千万行obs,没有问题的。
按照 ...
嗯。典型的“以空间换时间”的处理思路。
记得告诉大家你的结果。:-)
巫毒上传,必属佳品!
坛友下载,三思后行!

25
jonathanjp 发表于 2013-5-3 00:16:08
xingxf 发表于 2013-5-2 21:26
Nick的办法还是有启发的
Another tip from Michael Barker (Statalist)

-----------------------------------------------------------------

It looks like you are comparing each observation to every other observation in your data set. If your data are sorted, you only have to look back within each 5-year window for each id. If your data are sorted descending by date, the code would look like this:

gen temp = flag
local N = _N
forvalues i = 1(1)`N' {
local j=`i'+1
while (id[`i']==id[`j'] & (date[`i'] - date[`j'])/365.25 <= 5) {
replace temp = temp[`i'] + temp[`j'] in `i'
local j = `j'+1
}
}

If your data were sorted ascending by date, you would just iterate j
downwards (j = i-1, j=j-1) and start the "forvalues" loop at 2
(forvalues 2(1)`N' {)

-----------------------------------------------------------------
上面程序中的flag相当于你源数据中的B,temp为你要生成的变量。你可以在这里查看完整的回复
http://www.stata.com/statalist/archive/2013-05/msg00087.html
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
xingxf + 2 + 5 + 2 观点有启发

总评分: 学术水平 + 2  热心指数 + 5  信用等级 + 2   查看全部评分

26
xingxf 发表于 2013-5-3 01:45:10
voodoo 发表于 2013-5-2 23:19
嗯。典型的“以空间换时间”的处理思路。
记得告诉大家你的结果。:-)
我试了,如果样本小一些没问题,我这个样本按照我自己的那个算法obs要超过1亿了,32G内存全部吃满。不可行啊。

27
xingxf 发表于 2013-5-3 02:31:56
voodoo 发表于 2013-5-2 23:19
嗯。典型的“以空间换时间”的处理思路。
记得告诉大家你的结果。:-)
如果不用循环,下面的代码可行,但是要注意样本过大会超出内存容量。
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, full
gen sum_B=sum(total_B)
gen freq_B=l.sum_B-l1827.sum_B
gen sum_E=sum(total_E)
gen freq_E=l.sum_E-l1827.sum_E
gen sum_MA=sum(total_MA)
gen freq_MA=l.sum_MA-l1827.sum_MA

28
xingxf 发表于 2013-5-3 04:55:03
jonathanjp 发表于 2013-5-3 00:16
Another tip from Michael Barker (Statalist)

--------------------------------------------------- ...
这个程序我试了下,速度也慢,另外,我试了下,好像结果也不太对。

29
voodoo 发表于 2013-5-3 09:43:04
xingxf 发表于 2013-5-3 02:31
如果不用循环,下面的代码可行,但是要注意样本过大会超出内存容量。
bys id Date: egen total_B=total( ...
假如数据量较小的话(先“分而治之”?),这段程序可行。但tsfill也极为耗费时间,在我的电脑上保留前10000个样本,不用tsfill的full选项,程序运行总耗时11秒。那500000个样本,也要550秒。不见得比我15楼提出的程序节约多少时间。:-)

  1. /*
  2. set rmsg on
  3. use sample.dta, clear
  4. ren date Date
  5. keep in 1/1000
  6. */
  7. foreach v in B E MA {
  8.         bysort id Date: egen total_`v'=total(`v')
  9. }
  10. duplicates drop id Date, force
  11. egen ID=group(id)
  12. xtset ID Date
  13. // tsfill, full  // 应该无需, full选项,加入此选项将极大极大增加tsfill后的样本数,前1000->>2854800!全样本再大的内存也装不下的!
  14. tsfill  // 此时,tsfill后的样本数,前1000->221559
  15. count
  16. foreach v in B E MA {  // 27楼程序中有错误,修改啦
  17.         by ID: gen sum_`v' = sum(total_`v')
  18.         gen freq_`v' = cond(l.sum_`v'==., 0, l.sum_`v')-      ///
  19.                 cond(l1827.sum_`v'==., 0, l1827.sum_`v')
  20. }
  21. keep if !missing(id)
  22. // merge ...
复制代码

已有 1 人评分学术水平 热心指数 信用等级 收起 理由
xingxf + 5 + 5 + 5 观点有启发

总评分: 学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

巫毒上传,必属佳品!
坛友下载,三思后行!

30
voodoo 发表于 2013-5-3 10:13:02
jonathanjp 发表于 2013-5-3 00:16
Another tip from Michael Barker (Statalist)

--------------------------------------------------- ...
对于这方法,且不论其对错,第一感觉是:自己编写while ... {...}循环来完成summarize temp if (id==id[`i'] & inrange(date[`i'] - date), 1, 1826)),其执行效率应该不会比C语言(?)写的built-in command:  summarize的执行效率来得高。
巫毒上传,必属佳品!
坛友下载,三思后行!

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

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2025-12-6 02:42