sunshinegirl
sunshinegirl

Reputation: 81

Does a date occur within a specified period in SAS

I would like to know if my data would be included in a specified month. Please see reprex below:

id   Period_start    Period_end
1    01-01-2012      12-03-2015
1    21-03-2014      12-11-2014
2    09-05-2018      31-01-2019
3    08-12-2013      30-03-2015
3    26-03-2016      22-03-2020
4    31-07-2018      07-08-2018
4    29-09-2014      03-03-2017
4    13-06-2020      17-02-2021
4    23-01-2008      15-08-2016
4    05-10-2009      26-12-2015

I've tried the below codes using a single month. They worked the first time and did not work after that.

data dates2;
set work.dates;
by id;
if (period_start>='01MAR2016'd and period_end<='01MAR2016'd) or (period_start>='31MAR2016'd and period_end<='31MAR2016'd) then flag='March 2016';
else flag='';
run;

/* Or */

data dates2;
set work.dates;
by id;
if ('01MAR2016'd ge period_start and '01MAR2016'd le period_end) or ('31MAR2016'd ge period_start and '31MAR2016'd le period_end) then flag='March 2016';
else flag='';
run;

My intended outcome for this example is below:

id   Period_start    Period_end   Flag
1    01-01-2012      12-03-2015 
1    21-03-2014      12-11-2014
2    09-05-2018      31-01-2019
3    08-12-2013      30-03-2015
3    26-03-2016      22-03-2020   March 2016
4    31-07-2018      07-08-2018
4    29-09-2014      03-03-2017   March 2016
4    13-06-2020      17-02-2021
4    23-01-2008      15-08-2016   March 2016
4    05-10-2009      26-12-2015

Please note that I have a number of months to compare them against which is why I didn't use the where function.

Upvotes: 0

Views: 185

Answers (1)

Richard
Richard

Reputation: 27498

You can process multiple months to flag (i.e "number of months to compare") in one go if you store those months in a separate data set (as opposed to hard coding the month in a DATA Step program source code)

Example:

The months to flag are stored in a control data set, which, is then transposed to create flag variables. The flag variables are reloaded at every iteration of the DATA Step implicit loop using SET and POINT= and conditionally cleared based on date range comparison in an explicit loop over the flag variables.

data have;
attrib 
  id length=8
  period_start period_end informat=ddmmyy10. format=ddmmyyd10.;
input
id   Period_start    Period_end; datalines;
1    01-01-2012      12-03-2015
1    21-03-2014      12-11-2014
2    09-05-2018      31-01-2019
3    08-12-2013      30-03-2015
3    26-03-2016      22-03-2020
4    31-07-2018      07-08-2018
4    29-09-2014      03-03-2017
4    13-06-2020      17-02-2021
4    23-01-2008      15-08-2016
4    05-10-2009      26-12-2015
;

data flag_months;
attrib month informat=monyy7. format=monyy7.;
input month; datalines;
MAR2016
AUG2018
;

proc transpose data=flag_months out=flag_vars(drop=_name_) prefix=FLAG_;
  id month;
  var month;
run;

data want;
  set have;
  retain one 1;
  set flag_vars point=one; drop one;  * load flag values;
  array flag_vars flag_:;

  do _i_ = 1 to dim(flag_vars);
    * clear flag value if month does not touch any day in the period;
    if not 
    (  intnx('month', period_start, 0) 
       <=
       flag_vars(_i_) 
       <=
       intnx('month', period_end, 0, 'E')
    )
    then
      call missing(flag_vars(_i_));
  end;
run;

Flag months

enter image description here

Transposed into Flag vars

enter image description here

Which are loaded and conditionally cleared during a pass over the data set containing date range information.

enter image description here

Upvotes: 1

Related Questions