BluesGotTheCup
BluesGotTheCup

Reputation: 43

If-Else-Then with today()

i am currently trying to write some code that goes through my data and marks a number 0-12 based off the date in the "Week" column. this number appears in a new column called group which is created by the code you see below. The problem is that this column is periods all the way down and not numbers. There are no errors messages in the log so i dont know where i went wrong (im fairly new to sas). PS. the dates range from 6/17 to 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;

update: the first column is called week and is a monday date that goes 12 weeks into the future. the rest of the columns are variables that i will end up summing based on the group that row is in.

ex:

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

and it continues until 09sept2019.. it does this for each ID (roughly 10,000 of them) but not every id goes 12 weeks out thats why i am using the else if

i would like it to look like

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





Upvotes: 0

Views: 769

Answers (3)

Ben
Ben

Reputation: 489

Assuming week is date and not datetime.

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;
  • removed wrong answer.

Upvotes: 0

Tom
Tom

Reputation: 51566

It is not at all clear what you are trying to do. It sounds a little like you want to group observations based on how many weeks the date variable (called WEEK) is away from today's date. It might be easiest to just use the INTCK() function. That will count how many week boundary's are crossed between the two dates.

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;

You can then summarize the number of ID's per group.

proc freq data=want;
  tables group;
run;

Results:

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

Upvotes: 1

Richard
Richard

Reputation: 27508

A full reference to SAS operators can be found in SAS help by searching SAS Operators in Expression. SAS expressions can use some operators that are relatively unique across the spectrum of coding languages. Here are some that are not typically found in newly coded SAS (at time of this post)

  • <> MAX operator
  • >< MIN operator
  • implied AND operator

Two comparisons with a common variable linked by AND can be condensed with an implied AND.

So the uninitiated readers of the question may misunderstand

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

as incorrect, instead of recognizing it as an implied AND

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

When syntactically correct, the = in the implied AND causes the expression to be true only on equality. The week value in open interval ( today()+35, today()+34 ) will never evaluate as true in the above expression. This is the likely cause of the missing values (.) you are seeing.

  • Why does the code exhibit non-static delta of 7 in the sequence 30,23,16,11,2,-5 ?
  • Should it be 30,23,16,9,2,-5.
  • In other words why is group 1 apparently shooting for a 5 day range [+7, +2) when all the others are 3, such as [+14, +11) ?
  • Why are there 2-days domains, presumed weekends, in which group is not assigned, and would thus be missing (.) ?

This type of wallpaper code is often better represented by a an arithmetic expression.

For example, presuming integer SAS date values:

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;

Tomorrow the group value could 'wrong' because it is today() based. Consider coding a view instead of creating a permanent data set -- OR -- place meta information in the variable name group_on_20190622 = …

If you insist on wallpaper, consider using a select statement which is less prone to typing errors that can happen with errant semi-colons or missing elses.

Upvotes: 1

Related Questions