агрегат для перезаписи существующих данных

Я использовал следующий код, который отлично работает, чтобы получить следующие результаты:

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 поможет, но нет


person user2448666    schedule 16.10.2013    source источник


Ответы (3)


Что-то вроде этого должно работать. Выведите, если last.account_number, и используйте сохранить, чтобы сохранить значения в строках. Я использую объединение, чтобы установить нулевое значение, если оно не отсутствует, вы можете сделать это несколькими различными способами.

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;
person Joe    schedule 16.10.2013
comment
нет, это не так. Я хочу объединить все строки для данного номера учетной записи, чтобы значения недели перезаписывали существующие при каждом запуске. для accnt # 1 во второй строке есть 5 на третьей неделе, и это перезаписывает оставшиеся 1 из первой строки. - person user2448666; 16.10.2013

Предполагая, что я понимаю, что вы хотите сделать, попробуйте следующее:

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;

Единственное «правило», которое я вижу, это ваше желание сохранить последние ненулевые значения переменной. Пока ваши исходные данные упорядочены так, как они представлены, они должны работать.

person BellevueBob    schedule 17.10.2013

Если вы хотите, чтобы это было как proc 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 ;
person DTS    schedule 04.09.2014