我在下表的前四列中显示了信息,并希望添加列 Calls_previous_3_days ,其中包含每个CustID对前三个日期的每个区域的调用总和。
即如果客户在2015年1月17日拨打支持电话,我希望新变量显示客户在2015年1月14日至2015年1月14日期间支持的电话总数。
如何计算 Calls_previous_3_days 列中的总和,具体取决于CustID,面积和日期?
CustID Area Date Calls Calls_previous_3_days
3137 Support 05Jan2015 1 0
3137 Support 14Jan2015 4 0
3137 Support 16Jan2015 1 4
3137 Support 17Jan2015 1 5
3137 Support 20Jan2015 2 1
3137 Support 22Jan2015 1 2
5225 Support 26Jan2015 1 0
5225 Support 27Jan2015 1 1
5225 Support 28Jan2015 1 2
5225 Sales 14Feb2015 1 0
5225 Sales 15Feb2015 1 1
5225 Sales 22Feb2015 1 0
答案 0 :(得分:0)
您可以使用数组实现此目的,方法是存储最后三个值和日期,然后汇总日期满足条件的位置。
proc sort data = have;
by CustID Area;;
run;
proc print;
data want;
set have;
by CustID Area;
/* Create temporary array (which automatically retains) */
array hist{3,2} _temporary_;
/* Initialise the array values if starting a new group */
if first.Area then call missing(of hist[*]);
/* Sum the values in the array that satisfy your condition */
callsp3 = sum(
0,
(sum(Date, - hist[1,2]) <= 3) * hist[1,1],
(sum(Date, - hist[2,2]) <= 3) * hist[2,1],
(sum(Date, - hist[3,2]) <= 3) * hist[3,1]
);
/* Store the current value/date in the array and shift old values down */
hist[1,1] = hist[2,1];
hist[1,2] = hist[2,2];
hist[2,1] = hist[3,1];
hist[2,2] = hist[3,2];
hist[3,1] = Calls;
hist[3,2] = Date;
run;
(通常使用SAS)有几种方法可以解决这个问题。您还可以调查lag()
functions或使用proc sql
自我加入数据,并使用on
子句来指定您的条件。我更喜欢数组方法,因为lag()
有一些gotchas,自连接会慢一些。但是,如果您可能需要不同或更长的窗口,那么由于代码的长度,阵列方法可能会变得有些笨拙。如果您对宏语言有信心,可以减轻这种情况,但调查其他方法可能会更好。
如果您获得SAS / ETS许可,您应该可以使用proc expand
实现此目标。我不能确认这完全是你想要的,因为我没有许可证。
proc expand data = have out = want from = day to = day;
by CustID Area;
id Date;
convert calls = callsp3 / method = none transformout = (movsum 4);
run;
data want;
set want (where = (calls ~= .));
callsp3 = callsp3 - calls;
run;
答案 1 :(得分:0)
LAG功能,正如@SRSwift详细说明,当然效果很好。
此外,这是一个SQL解决方案。使用数据步骤将0替换为缺失,不确定SQL步骤中的CASE语句是否是最佳方法。
Data HAVE;
Input custid $ area $ date:date9. calls;
format date date9.;
datalines;
3137 Support 05Jan2015 1
3137 Support 14Jan2015 4
3137 Support 16Jan2015 1
3137 Support 17Jan2015 1
3137 Support 20Jan2015 2
3137 Support 22Jan2015 1
5225 Support 26Jan2015 1
5225 Support 27Jan2015 1
5225 Support 28Jan2015 1
5225 Sales 14Feb2015 1
5225 Sales 15Feb2015 1
5225 Sales 22Feb2015 1
;
Run;
Proc sql;
Create table WANT as
Select custid,area,date,calls,
(select sum(calls) from have b where a.custid=b.custid and
a.area=a.area and (a.date-3<=b.date<a.date)) as Calls_Previous_3_Days
From HAVE a;
Quit;
Data WANT;
Set WANT;
If missing(calls_previous_3_days) then Calls_Previous_3_Days=0;
Run;