Sas 聚合以覆盖现有数据
我使用了下面的代码,它工作得非常好,以获得以下结果:Sas 聚合以覆盖现有数据,sas,proc-sql,Sas,Proc Sql,我使用了下面的代码,它工作得非常好,以获得以下结果: data No_int_weeksPaid; set no_internet4; keep account_number week0-week61; by account_number; array week{62} week0-week61; do i = 1 to 62; if i > subscription_start and i <= (subscription_end+1) then week{i} =
data No_int_weeksPaid;
set no_internet4;
keep account_number week0-week61;
by account_number;
array week{62} week0-week61;
do i = 1 to 62;
if i > subscription_start and i <= (subscription_end+1) then
week{i} = weeks_paid ;
else
week{i} = 0;
end;
drop i;
run;
我希望将所有帐户#都放在一行上,并覆盖这些值,以便得到如下结果:
Account# Week0 week1 week2 week3 week4
1 0 1 1 1 1
1 0 0 0 5 5
2 1 1 1 1 1
2 0 2 2 2 2
2 0 0 0 4 4
Account# Week0 week1 week2 week3 week4
1 0 1 1 5 5
2 1 2 2 4 4
我原以为by语句会有帮助,但不,像这样的东西应该行得通。输出if last.account\u编号,并使用retain跨行保留值。我使用coalesce将非missing设置为零,您可以通过几种不同的方法来实现
data No_int_weeksPaid;
set no_internet4;
keep account_number week0-week61;
retain week0-week61; **CHANGED**
by account_number;
array week{62} week0-week61;
do i = 1 to 62;
if i > subscription_start and i <= (subscription_end+1) then
week{i} = weeks_paid ;
else
week{i} = coalesce(week[i],0); **CHANGED**
end;
drop i;
if last.account_number then output; **CHANGED**
run;
data No_int_weeksPaid;
不设互联网4;
保持账号为第0周至第61周;
保留第0周至第61周**改变**
按账号;
阵列周{62}周0-61周;
i=1到62;
如果i>subscription\u start并且i假设我了解您想要做什么,请尝试以下操作:
data have;
input Account Week0 week1 week2 week3 week4;
datalines;
1 0 1 1 1 1
1 0 0 0 5 5
2 1 1 1 1 1
2 0 2 2 2 2
2 0 0 0 4 4
run;
data want;
set have(rename=(Week0=oWeek0 Week1=oWeek1 Week2=oWeek2
Week3=oWeek3 Week4=oWeek4));
by account;
retain Week0 Week1 Week2 Week3 Week4;
array new{*} Week0 Week1 Week2 Week3 Week4;
array old{*} oWeek0 oWeek1 oWeek2 oWeek3 oWeek4;
keep Account Week0 Week1 Week2 Week3 Week4;
if First.account then
do i=1 to dim(new);
new{i} = old{i};
end;
else do i=1 to dim(new);
if old{i} ne 0 then new{i} = old{i};
end;
if last.Account;
run;
我看到的唯一“规则”是希望保留变量的最后一个非零值。只要您的原始数据按显示顺序排列,它就应该可以工作。如果您希望将其作为过程sql
,可能最容易构建一个快速宏来为您执行迭代:
%MACRO Week(W) ;
%DO N=1 %TO &W ;
max(Week&N) as Week&N,
%END ;
0 as _null_
%END ;
proc sql ;
create table output as
select Account, %Week(61)
from No_int_weeksPaid
group by Account
;
quit ;
不,不是这样。我希望合并给定帐号的所有行,以便无论何时开始,week的值都会覆盖现有的行。对于accnt#1,第二行在第三周有一个5,这将覆盖第一行的剩余1。