SAS:如何将组中排名较高的第一个值分配给整个组

时间:2014-11-18 14:48:49

标签: sas proc-sql

在SAS中,如何将组中排名较高的第一个评级值分配给整个组。 见下面的数据集

ID  Rating  Price   Rt_Rank
AN  A       105     0
AN  B3      200     1
IG  A2      705     0
IG  A       700     1
IG  HY      102     1
IG  NR      1005    1
RS  HY      20      1
AK  NR      803     0
DC  A       0       0
DC  NR      12000   0

如果组rt_rank为1,那么我想将第一个评级值分配给整个组。

所需数据集:

ID  Rating  Price   Rt_Rank Rating_grp
AN  B       105     0       B3
AN  B3      200     1       B3
IG  A2      705     0       A
IG  A       700     1       A
IG  HY      102     1       A
IG  NR      1005    1       A
RS  HY      20      1       HY
AK  NR      803     0       NR
DC  A       0       0       NR
DC  NR      12000   0       NR

我通过创建中间数据集并使用此第一个评级值创建临时变量然后将其与原始数据集合并来实现此rating_grp。 但我想知道是否有另一种简单的方法来做到这一点。

提前致谢!

1 个答案:

答案 0 :(得分:0)

如果所有评级值的等级为0,则不清楚要使用的规则。但是,以下内容非常接近您的要求。它使用双DOW循环计算每个ID by-group中的滚动最大值,然后将其附加到该组中的每个记录。这意味着您必须两次读取输入数据集,但不要生成中间数据集。

您发布的示例数据未按ID排序,因此我假设如果在非连续行中出现两次相同的ID,则需要为每个实例计算单独的rating_grp值。

data have;
    length ID RATING $2;
    input ID $ Rating $  Price  Rt_Rank;
    cards;
AN  A       105     0
AN  B3      200     1
IG  A2      705     0
IG  A       700     1
IG  HY      102     1
IG  NR      1005    1
RS  HY      20      1
AK  NR      803     0
DC  A       0       0
DC  NR      12000   0
;
run;

data want;
    if 0 then set have; /*Make sure columns are in correct order in output dataset*/
    length rating_grp $2;
    max_rank = -1; /*Before we start each by group, reset the rolling max*/
    call missing(rating_grp);
    do until(last.ID); /*Work through each by group keeping a rolling max*/
        set have;
        by ID notsorted;
        if rt_rank > max_rank then do; /*Update rating_grp each time a new max is reached*/
            max_rank = rt_rank;
            rating_grp = rating;
        end;
    end;
    do until(last.ID); /*Work through the by group a second time, this time outputting all records*/
        set have;
        by ID notsorted;
        output;
    end;
    drop max_rank;
run;