如何使用SAS创建基于前期绩效的排名

时间:2015-07-06 21:21:27

标签: sas

我的数据集如下所示。我想根据他前一天的表现对每个名字进行排名。如果class的{​​{1}}在第t天排名为前10%(20%),则第t + 1天的sales排名应为1(2)。同样,如果name的{​​{1}}在第t天排名为最低10%,则第t + 1天的name排名应为10.

sales

到目前为止我所做的是: 步骤1.按name name对数据进行排序 第2步。创建new_variable name date sales rank a day1 11 b day1 20 c day1 15 d day1 8 a day2 12 b day2 21 c day2 16 d day2 9 a day3 7 b day3 14 c day3 12 d day3 10 date。我是每个sales上名字i的确切排名。 i衡量每个N的观察总数。如果date / N小于.1,则date = 10,等等。这个新变量I将是第t天N的排名。

但是,我不知道如何将今天的排名Rank_previous指定为第二天Rank_previous。因为,我的数据集非常大,如果您有更有效的方法来解决这个问题,那将会很棒。

name

4 个答案:

答案 0 :(得分:2)

计算排名的最简单方法是,不出所料,给出SAS的命名法,PROC RANK。为此,必须先对数据进行排序by date

data have;
input name   $ date   $ sales;
datalines;
a      day1     11
b      day1     20
c      day1     15
d      day1     8
a      day2     12 
b      day2     21
c      day2     16
d      day2     9
a      day3     7 
b      day3     14
c      day3     12
d      day3     10
;;;;
run;

proc rank data=have out=ranks percent;
by date;
var sales;
ranks rank;
run;

percent参数要求百分位数而非数字排名。可能为您提供所需排名的另一个选项是groups=10,它会将所有值分配给十个组中的一个,但有时使用原始百分位数并自行分配(更好地处理关系等)更容易。您也可以使用descending以相反的顺序进行分配,因为我不清楚您打算采用何种顺序。

当然,正如你想要 next 那天的排名一样,你需要有一个简短的datastep来将日期增加一个并重新合并,或者SQL连接,或者任何你偏爱。

答案 1 :(得分:1)

使用2组临时ARRAY:一组用于保存前一天的排名,另一组用于创建当天的排名。

当您点击当天的LAST.date时,您可以输出当天的所有信息,包括前几天的排名。然后,将今天的排名复制到前一天的排名。

这样,您只需在按日期和销售排序后对其进行一次数据处理。

答案 2 :(得分:1)

首先让我们加载比示例更多的数据:

data have;
input name   $ date   $ sales;
datalines;
a      day1     11
b      day1     20
c      day1     15
d      day1     8
a      day2     12 
b      day2     21
c      day2     16
d      day2     9
e      day2     1
f      day2     90
g      day2     99
h      day2     2
i      day2     70
j      day2     39
k      day2     1
l      day2     16
m      day2     90
a      day3     7 
b      day3     14
c      day3     12
d      day3     10
;
run;

由于性能很重要,我会选择PROC MEAN(这是proc类的扩展版本,可以保留小计并且非常有效.class子句对应于proc类中的by子句)

proc means data=have noprint;
class date sales name;
output out=haveMean (where=(_type_ in (4,7)));

小计和细节由类型命名。省略where子句以找出哪种类型具有哪些数据。 现在合并 type 4: freq 从中获取当天活跃的销售人员数量和类型 7:详细信息

data salesSum;
merge haveMean (where=(_type_ eq 4) rename=(_freq_=numberPerDay) drop=name sales)
      haveMean (where=(_type_ eq 7));
by date;

跟踪当天的订单编号,将其除以活跃销售人员的编号

retain orderInDay rank;
if first.date then orderInDay = 1; else orderInDay = orderInDay+ 1;

仅计算具有特定销售量的第一次观察的等级,给出相同的等级

if first.date or lag1(sales) NE sales then rank = ceil(10 * orderInDay / numberPerDay);

打印相关内容

proc print data=salesSum;
by date;
var name sales rank;
run;

此解决方案仍然错过了将排名移至下一个工作日的方法。我考虑为此使用哈希表。

答案 3 :(得分:1)

**首先让我们加载比示例更多的数据:**;

data have;
input name   $ date   $ sales;
datalines;
a      day1     11
b      day1     20
c      day1     15
d      day1     8
a      day2     12 
b      day2     21
c      day2     16
d      day2     9
e      day2     1
f      day2     90
g      day2     99
h      day2     2
i      day2     70
j      day2     39
k      day2     1
l      day2     16
m      day2     90
a      day3     7 
b      day3     14
c      day3     12
d      day3     10
e      day4     1
f      day4     90
g      day4     99
h      day4     2
i      day4     70
j      day4     39
k      day4     1
l      day4     16
m      day4     90
;
run;

**然后,正如Joe教导我们的那样,让我们​​应用proc等级。我们需要排名,而不是销售,所以让我们摆脱它**;

proc rank  groups=10
    data=have 
    out=ranks  (drop=sales);

    by date;
    var sales;
    ranks rank_previous;
run;

**现在将前一天的排名与今天的销量合并,我们需要一点点memery **;

data have_memory;
    set have;
    by date;

    retain date_previous;
    if first.date then date_previous = lag1(date);
run;

**现在经典合并可以完成工作**;

data have_ranked (drop=date_previous);
    merge have_memory (in=has)
          ranks (rename=(date=date_previous));
    by date_previous name;

    if not has then date = 'next';
run;