If-Else-Тогда с сегодняшнего дня () - PullRequest
0 голосов
/ 21 июня 2019

В настоящее время я пытаюсь написать какой-нибудь код, который просматривает мои данные и помечает число 0-12 на основе даты в столбце «Неделя». этот номер появляется в новом столбце под названием group, который создается кодом, который вы видите ниже. Проблема в том, что в этом столбце есть периоды, а не числа. В журнале нет сообщений об ошибках, поэтому я не знаю, где я ошибся (я довольно новичок в sas). PS. даты варьируются от 6/17 до 9/9

data have;
set have;
if today()+84 = Week > today()+79 then group=12;
else if today()+77 = Week > today()+72 then group=11;
else if today()+70 = Week > today()+65 then group=10;
else if today()+63 = Week > today()+58 then group=9;
else if today()+56 = Week > today()+51 then group=8;
else if today()+49 = Week > today()+45 then group=7;
else if today()+42 = Week > today()+37 then group=6;
else if today()+35 = Week > today()+30 then group=5;
else if today()+28 = Week > today()+23 then group=4;
else if today()+21 = Week > today()+16 then group=3;
else if today()+14 = Week > today()+11 then group=2;
else if today()+7  = Week > today()+2 then group=1;
else if today()    = Week > today()-5 then group=0;
run;

Обновление: первый столбец называется неделей и является датой понедельника, которая уходит на 12 недель в будущее. остальные столбцы - это переменные, которые я суммирую в зависимости от группы, в которой находится строка.

например:

  week       ID var2 ... var18
    17jun2019 1    x        x   
    24jun2019 1    x        x

и это продолжается до 09sept_2019 .. оно делает это для каждого идентификатора (примерно 10 000 из них), но не каждый идентификатор проходит 12 недель, поэтому я использую else, если

Мне бы хотелось, чтобы это выглядело

   week      ID var2 ... var18 group
    17jun2019 1    x        x    0
    24jun2019 1    x        x    1
    01july2019 1   x        x    2





Ответы [ 3 ]

1 голос
/ 22 июня 2019

Полную ссылку на операторов SAS можно найти в справке SAS, выполнив поиск SAS Operators in Expression.В выражениях SAS могут использоваться некоторые операторы, которые являются относительно уникальными по всему спектру языков кодирования.Вот некоторые из них, которые обычно не встречаются во вновь закодированном SAS (на момент публикации)

  • <> оператор MAX
  • >< оператор MIN
  • подразумевается AND оператор

Два сравнения с общей переменной, связанной с И, могут быть сжаты с подразумеваемым И.

Такнепосвященные читатели вопроса могут неправильно понять

… 
if today()+35 = Week > today()+30 then group=5;
… 

как неверный, вместо того, чтобы признать его как подразумеваемый И

… 
if today()+35 = Week   AND   Week > today()+30 then group=5;
… 

Когда синтаксически правильно, = в implied AND заставляет выражение быть истинным только на равенстве.Значение недели в открытый интервал (сегодня () + 35, сегодня () + 34) никогда не будет оцениваться как истинное в вышеприведенном выражении.Это вероятная причина пропущенных значений (.), которые вы видите.

  • Почему код демонстрирует нестатическую дельту 7 в последовательности 30,23,16,11,2,-5?
  • Должно ли это быть 30,23,16,9,2,-5.
  • Другими словами, почему группа 1, очевидно, стреляет для 5-дневного диапазона [+7, +2), когда все остальные 3, например [+14, +11)?
  • Почему существуют двухдневные домены, предполагаемые выходные, в которых группа не назначена и, следовательно, будет отсутствовать (.)?

Этот тип кода обоев часто лучше представить арифметическим выражением.

Например, предполагая целочисленные значения даты SAS:

group = ifn ( MOD (week-today(), 7) in (1,2)
            , .
            , CEIL (week-today() / 7 )
            );

if not ( 0 <= group <= 12 ) then group = .; * probably dont want this but makes it compliant with OP;

Завтра значение группы может 'неправильно', потому что это сегодня ().Попробуйте создать код вместо создания постоянного набора данных - ИЛИ - поместите метаинформацию в имя переменной group_on_20190622 = …

Если вы настаиваете на обоях, рассмотрите возможность использования selectоператор, который менее подвержен ошибкам ввода, которые могут произойти с ошибочными точками с запятой или отсутствующими символами.

1 голос
/ 23 июня 2019

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

data have ;
  input id week date9.;
  format week date9.;
cards;
1 17jun2019
1 24jun2019
1 01jul2019
2 24jun2019
2 01jul2019
2 08jul2019
;

data want ;
 set have;
 group = intck('week',today(),week);
run;

Затем вы можете суммировать количество идентификаторов на группу.

proc freq data=want;
  tables group;
run;

Результаты:

The FREQ Procedure

                                  Cumulative    Cumulative
group    Frequency     Percent     Frequency      Percent
----------------------------------------------------------
   -1           1       16.67             1        16.67
    0           2       33.33             3        50.00
    1           2       33.33             5        83.33
    2           1       16.67             6       100.00
0 голосов
/ 21 июня 2019

Предполагая, что неделя - это дата, а не дата / время.

data test;
do i = 1 to 30;
 dt = intnx('day',today(),1*i);
 output;
end;
format dt date9.;
run;


data test2;
set test;
if dt ge today() and dt le today()+7 then dt2 = 1;
else if dt ge today()+8 and dt le today()+14 then dt2 = 2;
else if dt ge today()+15 and dt le today()+21 then dt2 = 3;
else if dt ge today()+22 and dt le today()+28 then dt2 = 4;
else if dt ge today()+29 and dt le today()+35 then dt2 = 5;
/* another way */
dt3 = ceil(intck('day',today(),dt)/7); 
run;
  • удален неправильный ответ.
...