sas count изменения между датой и переменной сгруппированы по id - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь получить количество изменений в переменной по умолчанию на основе идентификатора и даты. Мне неделя использования SAS, поэтому, пожалуйста, прости меня, если мне нужны подробные объяснения.

У меня сейчас есть

data test111;
input Date $ Acc $ Default $;
datalines;
jan-10 A N
feb-10 A D
mar-10 A D
apr-10 A D
may-10 A D
jan-10 B N
feb-10 B N
mar-10 B D
apr-10 B D
may-10 B D
jan-10 C N
feb-10 C N
mar-10 C N
apr-10 C D
may-10 C D
jan-10 D N
feb-10 D D
mar-10 D N
apr-10 D D
may-10 D D
jan-10 E D
feb-10 E D
mar-10 E D
apr-10 E N
may-10 E D

Я хочу вывод (таблица 1 ниже), который учитывается при изменении значения по умолчанию с N на D для каждой уникальной учетной записи. Но это зависит от даты. Я только знаю, как использовать Excel, чтобы показать желаемый результат (ручной подсчет). Таблица 2 показывает, как учитываются счета, если мне неясно.

Table 1
    month+1 month+2 month+3 month+4
Jan-10  2   1   1   0
Feb-10  1   1   0   
Mar-10  2   0       
Apr-10  1           

Table 2 (FYR)               
    month+1 month+2 month+3 month+4
Jan-10  A,D B   C   -
Feb-10  B   C   -   
Mar-10  C,D -       
Apr-10  E           

Я пробовал что-то вроде создания нового столбца, который помечает, когда N меняется на D, поэтому я могу суммировать, когда tag = 1

by first.Acc
if first.Acc then tag = 0;
if default = 'D' then do;
tag = 1;
tag+1;

Не уверен, что это даст мне правильный результат для моей первой строки. Но если это работает, он может дать мне только первый ряд желаемого результата. У меня более 100 месяцев, и можно ли это зациклить или упорядочить?

На случай, если мои навыки ввода данных SAS потерпят неудачу, я включил скриншот Excel. Снимок экрана Excel

1 Ответ

0 голосов
/ 04 июля 2018

Самое общее решение будет включать полное внешнее объединение в каждой группе.

SQL может выполнять объединение и вычислять месяцы отдельно для случая месяца с N по умолчанию до следующего самого раннего месяца с D по умолчанию. Табуляция может представлять сетку отсчетов.

Данные

Строки месяца преобразуются в значения даты SAS 1-го числа месяца, отформатированные yymon для целей отображения.

data have;
input Date $ Acc $ Default $;
month = input ('01-'||date, date9.);
format month yymon.;
datalines;
jan-10 A N
feb-10 A D
mar-10 A D
apr-10 A D
may-10 A D
jan-10 B N
feb-10 B N
mar-10 B D
apr-10 B D
may-10 B D
jan-10 C N
feb-10 C N
mar-10 C N
apr-10 C D
may-10 C D
jan-10 D N
feb-10 D D
mar-10 D N
apr-10 D D
may-10 D D
jan-10 E D
feb-10 E D
mar-10 E D
apr-10 E N
may-10 E D
run;

Пример SQL

proc sql;
  create view have_v as
  select 
    left.acc
  , left.month as from_month
  , right.month as to_month
  , intck ('MONTH', left.month, right.month) as months_apart
  from 
    have as left
    join have as right on left.acc = right.acc
    where 
      left.month < right.month
    & left.default = 'N'
    & right.default = 'D'
  group by left.acc, left.month
  having right.month = min(right.month)
  order by
    left.month, right.month
  ;

  create table grid_bounds as
  select 
    min(from_month) as min_from
  , max(from_month) as max_from
  , 1 as min_apart
  , max(months_apart) as max_apart
  from have_v
  ;

Объяснение SQL

Самостоятельное соединение - это соединение таблицы с самим собой.

have as left join have as right

Ограничение объединения ограничивает месячные комбинации from/to только теми, которые находятся в одной учетной записи

on left.acc = right.acc

Ограничение where дополнительно ограничивает комбинации from/to только теми, которые имеют to в будущем и имеют желаемый default переход

.
where 
  left.month < right.month
& left.default = 'N'
& right.default = 'D'

Оператор group by и функция автоматического повторного предложения в предложении SAS Proc SQL having позволяют с помощью простого оператора выбрать самый ранний to для данного from

group by left.acc, left.month
having right.month = min(right.month)

Для выбранных строк объединения месяцы могут быть вычислены с использованием функции данных SAS INTCK (я думаю, что имя функции является аббревиатурой для фразы "INTerval Count of the kind вида")

, intck ('MONTH', left.month, right.month) as months_apart

Конкретное решение может использовать массив, если известен самый большой размер группы apriori.

Таблица для вывода

Некоторые месяцы могут отсутствовать из-за отсутствия переходов. Кроме того, некоторые пробелы также могут отсутствовать. В этих случаях не будет строк в have_v. Чтобы получить полное покрытие для отчета, все возможные пересечения (или комбинации) создаются для использования в Proc TABULATE

proc sql;
  create table grid_bounds as
  select 
    min(from_month) as min_from
  , max(from_month) as max_from
  , 1 as min_apart
  , max(months_apart) as max_apart
  from have_v
  ;
quit;

data grid (label="All crossings to be shown in the output");
  set grid_bounds;
  do from_month = min_from to max_from;
    do months_apart = 1 to max(12,max_apart);
      OUTPUT;
    end;
  end;
  keep from_month months_apart;
  format from_month yymon.;
run;

Выводит отчет сетки с частотами разрыва для каждого из_месяц

options missing = '0' nocenter;

title "Account frequency";
title2 "Gap of month default changing from N to D";

proc tabulate data=have_v classdata=grid;
  class from_month months_apart;

  table 
    from_month=''
    , months_apart * N=''
  ;
run;

options missing = '.';
...