0

I used the following code, which works perfectly, to get the results that follow:

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;

gives me something like this:

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

I want to have all account#'s on one row and overwrite the values so that I get something like this:

 Account#   Week0   week1 week2  week3 week4
 1          0        1     1      5     5
 2          1        2     2      4     4

I thought the by statement would help, but nope

user2448666
  • 329
  • 1
  • 6
  • 14

3 Answers3

0

Something like this should work. Output if last.account_number, and use retain to keep the values across rows. I use coalesce to set to zero if nonmissing, you can do that a few different ways.

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;
Joe
  • 62,789
  • 6
  • 49
  • 67
  • no, that's not it. I want to merge all rows for a given account number so that the values of week overwrite the existing ones whenever they start. for accnt# 1, the second row has a 5 in week three and that overwrites the remaining 1's from the first row. – user2448666 Oct 16 '13 at 18:05
0

Assuming I understand what you want to do, try this:

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;

The only "rule" I see is your desire to retain the last non-zero values of the variable. As long as your original data is ordered as presented, it should work.

BellevueBob
  • 9,498
  • 5
  • 29
  • 56
0

If you want it as a proc sql, probably easiest to build a quick macro to do your iterations for you:

%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 ;
DTS
  • 423
  • 2
  • 13