楼主: xingxf
22805 41

[编程问题求助] 数据分组并标记 [推广有奖]

  • 0关注
  • 50粉丝

已卖:3687份资源

副教授

12%

还不是VIP/贵宾

-

威望
0
论坛币
60582 个
通用积分
772.5645
学术水平
224 点
热心指数
251 点
信用等级
138 点
经验
20775 点
帖子
753
精华
0
在线时间
522 小时
注册时间
2011-3-12
最后登录
2025-4-1

楼主
xingxf 发表于 2013-1-25 12:08:25 |AI写论文
1000论坛币
现有如下面板数据
ID     Year          Var1              Var2      Var3

A       2000        123897         1.2

A       2001        897650         3.5
A       2002        345687         2.2
...
A       2010        65789           3.3
B       2000        90876           2.5
...  
B       2010        54321           6.2
...
ZZ     2010        66880           9.9

现需要每年按照Var1数值大小排序分为10等分组,并在每十分之一组中按照Var2数值大小排列分为5等分组,需要在Var3中生成对应ID相应年份的组别。

其实有一个函数cut可以进行分组,egen size_decile=cut(Var1), group(10)
但是这个函数stata显示不能与by搭配使用,也就是说它不能按每一年分组



谢谢!!!

sungmoo已提供答案
但是取整函数int会造成第一分组观察值少一些,最后分组观察值多一些,受sungmoo的启发我改写程序如下:
gen MV_Deciles=1
forvalues i=1/10{
bys Year (MV): replace MV_Decile=`i' if 10*_n/_N<=`i'&10*_n/_N>`i'-1
}
gen MB_Quintiles=1
forvalues i=1/5{
bys Year MV_Deciles (MB): replace MB_Quintiles=`i' if 5*_n/_N<=`i'&5*_n/_N>`i'-1
}


sungmoo提供的改进答案:
bys Year (MV MB): g p=ceil(10*_n/_N)
bys Year p (MB MV): g q=ceil(5*_n/_N)
效果和我写的循环一样,执行效率却高很多。还是要熟悉各种函数啊。





liangsky提出如果样本中重复值较多,可能出现相同值分在不同组的情况,并提供如下代码。
gen n1=.
forv i=2000/2010 {
xtile n`i'=var1 if year==`i',n(10)
replace n1=n`i' if year==`i'
drop n`i'
}
gen n2=.
forv i=2000/2010 {
forv j=1/10 {
xtile n`i'`j'=var2 if year==`i' & n1==`j',n(5)
replace n2=n`i'`j' if year==`i' & n1==`j'
drop n`i'`j'
}
}
此方法分组准确稳妥,但是循环的执行效率不如直接使用函数快。


sungmoo提出cumul函数可以结合by使用解决以上所有问题,
最后我改写程序如下:bys year: cumul(MV), gen (cumMV) equal
gen MV_Deciles=ceil(10*cumMV)
bys year MV_Deciles: cumul(MB), gen (cumMB) equal
gen M2B_Quintiles=ceil(5*cumMB)



最佳答案

sungmoo 查看完整内容

*把缺失值去除,且年份仍然是最高分组 use example,clear drop if MV==.|MB==. bys Year (MV MB): g p=ceil(10*_n/_N) bys Year p (MB MV): g q=ceil(5*_n/_N)
关键词:数据分组 forvalues forvalue sungmoo replace

回帖推荐

liangsky 发表于19楼  查看完整内容

gen n1=. forv i=2000/2010 { xtile n`i'=var1 if year==`i',n(10) replace n1=n`i' if year==`i' drop n`i' } gen n2=. forv i=2000/2010 { forv j=1/10 { xtile n`i'`j'=var2 if year==`i' & n1==`j',n(5) replace n2=n`i'`j' if year==`i' & n1==`j' drop n`i'`j' } }

沙发
sungmoo 发表于 2013-1-25 12:08:26
*把缺失值去除,且年份仍然是最高分组
use example,clear
drop if MV==.|MB==.
bys Year (MV MB): g p=ceil(10*_n/_N)
bys Year p (MB MV): g q=ceil(5*_n/_N)
已有 2 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
Sunknownay + 100 + 10 + 1 + 1 + 1 热心帮助其他会员
xingxf + 5 + 5 + 5 观点有启发

总评分: 经验 + 100  论坛币 + 10  学术水平 + 6  热心指数 + 6  信用等级 + 6   查看全部评分

藤椅
dxystata 发表于 2013-1-25 12:51:14
可否传部分数据上来?

板凳
xingxf 发表于 2013-1-26 05:36:26
dxystata 发表于 2013-1-25 12:51
可否传部分数据上来?
这是一个示例文件,需要每年按照MV大小将ticker分为10组,在分好的每一组中,按照MB大小分为5组。
您看看有什么好方法么?
我目前有一个笨办法可以做,就是用cut函数,对每一年数据分组。
example.rar (2.07 MB) 本附件包括:
  • example.dta

报纸
sungmoo 发表于 2013-1-26 07:49:40
当MV或MB有缺失值时,处理规则是什么?
把缺失值drop掉就可以
*drop的规则是?

drop if MV==.|MB==.

地板
xingxf 发表于 2013-1-26 08:19:27
sungmoo 发表于 2013-1-26 07:49
当MV或MB有缺失值时,处理规则是什么?
把缺失值drop掉就可以

7
xingxf 发表于 2013-1-26 08:51:03
sungmoo 发表于 2013-1-26 08:05
*把缺失值去除,且年份仍然是最高分组
use example,clear
drop if MV==.|MB==.
不好意思,int函数的全称和功能是什么啊?
也许我没表达清楚意思,我是要求每年都要进行分组,分组的依据是根据MV数值大小分成10组,每一组再根据MB数值大小分成5组。
根据您的程序,我进行了sum
bys p: sum MV
结果显示几乎每组的最大值均超过下一组别的最小值,换句话说,这个分组不是按照MV值大小排序的。
所以这个不符合我说的要求。

8
sungmoo 发表于 2013-1-26 09:08:02
我是要求每年都要进行分组,分组的依据是根据MV数值大小分成10组,每一组再根据MB数值大小分成5组。
根据您的程序,我进行了sum
bys p: sum MV
楼主若“每年分组”,应该是"bys Year p: ……"吧?
int函数的全称和功能是什么啊?
取整函数

9
xingxf 发表于 2013-1-26 09:19:10
sungmoo 发表于 2013-1-26 09:08
楼主若“每年分组”,应该是"bys Year p: ……"吧?
哈哈,刚才疏忽了。验证了,没问题,非常感谢!
我再研究一下。

10
xingxf 发表于 2013-1-26 09:36:37
sungmoo 发表于 2013-1-25 12:08
*把缺失值去除,且年份仍然是最高分组
use example,clear
drop if MV==.|MB==.
真是巧妙啊,巧用取整,_n/_N就解决了。用最简单的公式,就是没想到。
还有个问题,bys Year (MV MB),这个括号是什么意思?这里面我直接bys Year MV:不也可以么?

我自己看了帮助文档,知道括号的意思了。不过第一次按MV分组的时候不用加上MB吧,bys Year (MV) 就好了吧?

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

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