SAS中文论坛

标题: 如何求百分位 [打印本页]

作者: shiyiming    时间: 2010-9-15 18:56
标题: 如何求百分位
有个数据集有个5个变量a b c d e f,我想求出五个变量都拍在所在列前30%的观测值,请问有什么方法可以快速实现呢,谢谢。
作者: shiyiming    时间: 2010-9-16 05:26
标题: Re: 如何求百分位
[code:2e4p1ytq]proc rank data = have out = rank_out groups = 100;
        var a b c d e f;
        ranks rank_a rank_b rank_c rank_d rank_e rank_f;
run;

data final;
        set rank_out;
        if max(of rank_:) < 30;
run;[/code:2e4p1ytq]
对排行的定义受对ties 如何处理的影响。对百分位的定义当然和proc univariate的定义也不同,虽然本质上差异不大。假定你的列前是从小往大数。
作者: shiyiming    时间: 2010-9-16 09:25
标题: Re: 如何求百分位
函数PCTL也可以。
proc univariate也不错。

ps:jingju测试过么?
作者: shiyiming    时间: 2010-9-16 12:07
标题: Re: 如何求百分位
我的理解是:pctl() 和univarite有同样的对percentile定义。rank此处在本质上有标定顺序的感觉。如果说univariate的percentile可以不是数列中的某个数,而在rank里是不可能造数的。他的问题应该不会是需要对百分数的精确定义的。
话说回来,univariate里的定义应该就是sas在统计角度上对percentile的定义。所以你的建议是属于精益求精一类的。
作者: shiyiming    时间: 2010-9-16 22:23
标题: Re: 如何求百分位
你给的方法已经很方便了。
作者: shiyiming    时间: 2010-9-17 07:08
标题: Re: 如何求百分位
to jingju11
I usually do this:
******************************************;
data _null_;
       set original nobs=ntotal;
       setn=int(ntotal*0.3);
       call symput('nextr', setn);
run;

ods select none;
ods output  ExtremeObs=ExtrObs;
proc univariate data=original  nextrobs=&nextr   def=1;
        var v1-v5;
run;
ods select all;

proc datasets library=work  nolist;
        modify ExtrObs;
        index create indexLow=(VarName LowObs)
                                   indexHigh=(VarName HighObs);
run;quit;
作者: shiyiming    时间: 2010-9-17 10:04
标题: Re: 如何求百分位
我总是忘我的,一次又一次充当先发言的,小学生。
作者: shiyiming    时间: 2010-9-17 11:18
标题: Re: 如何求百分位
<!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) --> 只能说是Lz似乎没描述得很清楚,
“百分位的前30%” 与 “前30%”之间有差异的。


[code:hlkz11hn]data ex;
input x1-x10;
x=pctl(30,of x1-x10);
cards;
1 2 3 4 5 6 7 8 9 10
1 3 3 3 5 6 7 8 9 10
1 3 3 3 3 6 7 8 9 10
;
run;
proc print;run;[/code:hlkz11hn]
作者: shiyiming    时间: 2010-9-17 19:51
标题: Re: 如何求百分位
用函数的方法,30%百分位以前(含)数。
ps:貌似sql不支持PCTL函数。

[code:zz5x9bgp]data original;
input v1-v5;
cards;
1        1        1        1        3
2        2        2        3        3
3        3        3        3        3
4        3        3        3        3
5        5        3        3        3
6        6        6        6        3
7        7        7        7        7
8        8        8        8        8
9        9        9        9        9
10        10        10        10        10
;
run;
proc transpose data=original out=ex(drop=_name_)  prefix=x;
run;
data ex2(keep=v);
   set ex;
        v=pctl(30,of x1-x10);
run;
proc transpose data=ex2 out=ex3(drop=_name_) prefix=c;
run;
data re;
     set original ;
     if _n_=1 then   set ex3;
         array c&#91;*&#93; c1-c5;
                 array v&#91;*&#93; v1-v5;
                 sum=0;
                 do i=1 to 5;
            sum+(c&#91;i&#93; ge v&#91;i&#93;);
                 end;
                 if sum eq 5 then output;
run;[/code:zz5x9bgp]
作者: shiyiming    时间: 2010-9-17 23:44
标题: Re: 如何求百分位
[quote=&quot;jingju11&quot;:mdgylakc]我总是忘我的,一次又一次充当先发言的,小学生。[/quote:mdgylakc]
支持以下版主,对错我从来不在乎,但你的方法完全满足楼猪"快速"的要求。
作者: shiyiming    时间: 2010-9-19 03:32
标题: Re: 如何求百分位
把问题延伸一下。假如我有一个比较大的数据集,百万行,上万列,数值型,不考虑tie,我现在只想要各列的前X%个观测值。如果数值稀疏造成有某个值覆盖的范围正好跨越这个X%,就任意选择其中K个,只要凑够这个X%就够。但是对应每个列的X不一样。比如我想取第一列的前15%,第二列的前5%,。。。。有啥高效的方法没有?

如果每一个X都比较小的话,我倒是有个hash的方法;如果比较大的话,就把数据集先变成长条形,然后BY 处理。还有其他方法没有?
作者: shiyiming    时间: 2010-9-19 10:03
标题: Re: 如何求百分位
这个问题不错,那是不是小于max(x%)的列需要用缺失值来填充?

这样的话,我上面转置的方法就很弱了,hash可以考虑;长条处理不错。也许SAS提供现成的proc还没被发现,data步里面有高效的办法也是很有可能的。
作者: shiyiming    时间: 2010-9-19 23:58
标题: Re: 如何求百分位
谢谢各位了,求教下为什么用PCTL函数求出1-10的30分位是3.5,但是EXCEL里面是3.7啊?




欢迎光临 SAS中文论坛 (http://www.mysas.net/forum/) Powered by Discuz! X3.2