SAS делает цикл с оператором if - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь сгруппировать по набору данных в трехмесячные группы или кварталы, но поскольку я начинаю с произвольной даты, я не могу использовать функцию квартала в sas.

Пример данных нижеиз того, что у меня есть, и четверть столбец, который мне нужно создать в SAS. Дата начала всегда одна и та же, поэтому мой начальный квартал будет 3 сентября 2018 г. - 3 декабря 2018 г., а любая активная дата, приходящаяся на этот квартал, будет 1, затем 2 квартал будет 3 декабря 2018 г. - 3 марта 2019 г. и т. Д.на.Это не может быть закодировано вручную, так как дата начала будет меняться в зависимости от данных, и число кварталов может быть до 20 +.

Код, который я пытался до сих пор, ниже

data test_Data_op;
set test_data end=eof;
%let j = 0;
%let start_date = start_Date;
if &start_Date. <= effective_dt < (&start_date. + 90) then quarter = &j.+1;
run;

Это работает и дает первый квартал правильно, но я не могу понять, как это зациклить для каждого следующего квартала?Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

1 голос
/ 24 сентября 2019

Нет необходимости в цикле DO, если у вас уже есть дата начала и фактические даты события.Просто посчитайте количество месяцев и разделите на три.Используйте непрерывный метод функции INTCK () для обработки дат начала, которые не являются первым днем ​​месяца.

month_number=intck('month',&start_date,mydate,'cont')+1;
qtr_number=floor((month_number-1)/3)+1;
1 голос
/ 24 сентября 2019

Основано на комментарии @Lee.Отредактировано в соответствии с данными из скриншота.

В примере показано, что 11 мая будет в 3-м квартале, поскольку начальная дата - 3 сентября.

data have;
input mydate :yymmdd10.;
format mydate yymmddd10.;
datalines;
2018-09-13
2018-12-12
2019-05-11
;
run;

%let start_date='03sep2018'd;

data want;
set have;
quarter=floor(mod((yrdif(&start_date,mydate)*4),4))+1;
run;

Если вы хотите числочетверть, чтобы выйти за пределы 4 (например, 4 сентября 2019 года будет в 5 квартале, а не возвращаться к 1), затем уберите «мод» из функции:

quarter=floor(yrdif(&start_date,mydate)*4)+1;
0 голосов
/ 24 сентября 2019

Традиционное использование квартал означает 3-месячный период времени по отношению к 1 января. Убедитесь, что ваша аудитория понимает фразу квартал в вашей презентации данных на самом деле означает 3 месяца по отношению к некоторымпроизвольная отправная точка.

Функциональный квартал может быть функционально вычислен из разницы месяцев, полученной с использованием комбинации INTCK для расчета базовых месяцев и логического выражения для корректировки по отношению к дню месяца даты начала.Никаких циклов не требуется.

Например:

data have;
  do startDate = '11feb2019'd ;
    do effectiveDate = startDate to startDate + 21*90;
      output;
    end;
  end;
  format startDate effectiveDate yymmdd10.;
run;

data want;
  set have;

  qtr = 1 
      + floor(
          ( intck ('month', startDate, effectiveDate) 
            -
            (day(effectiveDate) < day(startDate))
          ) 
          / 3
        );

  format qtr 4.;
run;

Extra

Сравнение моего метода (qtr) с @Tom (qtr_number) для диапазона начальных дат:

data have;
  retain seq 0;
  do startDate = '01jan1999'd to '15jan2001'd;
    seq + 1;
    do effectiveDate = startDate to startDate + 21*90;
      output;
    end;
  end;
  format startDate effectiveDate yymmdd10.;
run;

data want;
  set have;

  qtr = 1 
      + floor( ( intck ('month', startDate, effectiveDate) 
                 - (day(effectiveDate) < day(startDate))
               ) / 3 );

  month_number=intck('month',startDate,effectiveDate,'cont')+1;
  qtr_number=floor((month_number-1)/3)+1;

  format qtr: month: 4.;
run;

options nocenter nodate nonumber;title;
ods listing;

proc print data=want;
  where qtr ne qtr_number;
run;

dm 'output';

-------- ВЫХОД ---------

                                effective            month_     qtr_
    Obs    seq     startDate          Date     qtr    number    number

  56820     31    1999-01-31    1999-04-30       1        4         2
  57186     31    1999-01-31    2000-04-30       5       16         6
  57551     31    1999-01-31    2001-04-30       9       28        10
  57916     31    1999-01-31    2002-04-30      13       40        14
  58281     31    1999-01-31    2003-04-30      17       52        18
 168391     90    1999-03-31    1999-06-30       1        4         2
 168483     90    1999-03-31    1999-09-30       2        7         3
 168757     90    1999-03-31    2000-06-30       5       16         6
 168849     90    1999-03-31    2000-09-30       6       19         7
 169122     90    1999-03-31    2001-06-30       9       28        10
 169214     90    1999-03-31    2001-09-30      10       31        11
 169487     90    1999-03-31    2002-06-30      13       40        14
 169579     90    1999-03-31    2002-09-30      14       43        15
 169852     90    1999-03-31    2003-06-30      17       52        18
 169944     90    1999-03-31    2003-09-30      18       55        19
 280510    149    1999-05-29    2001-02-28       7       22         8
 280875    149    1999-05-29    2002-02-28      11       34        12
 281240    149    1999-05-29    2003-02-28      15       46        16
 282035    150    1999-05-30    2000-02-29       3       10         4
 282400    150    1999-05-30    2001-02-28       7       22         8
 282765    150    1999-05-30    2002-02-28      11       34        12

...