BookmarkSubscribeRSS Feed
catmad
Calcite | Level 5

I have a dataset whose column names are col_Dec16, col_Jan17, col_Feb17 and so on.

I have created 18 variables to hold a selection of column names as the report I need is to cover 18 months.

 


%let report_date = '15May2018'd;
data_null_; call symput('a01', cat('col_', put(intnx('month',&month1_date,2), monname3.), put(intnx('year',&report_date,-2), year2.))); /* Dec 2 years previous */ call symput('a02', cat('col_', put(intnx('month',&month1_date,3), monname3.), put(intnx('year',&report_date,-1), year2.))); /* Jan 1 years previous */ call symput('a03', cat('col_', put(intnx('month',&month1_date,4), monname3.), put(intnx('year',&report_date,-1), year2.))); /* Feb */ etc.....

I would like to create another set of variables that contain a list of the months I want to keep, depending on the month of reporting.

Something like;

if month(report_date) = May then keeplist = (&a01 &a02 &a03);

if month(report_date) = April then keeplist = (&a01 &a02);

 

I don't know if I can do it in a LET statement or if it has to be a macro.

Here's what I've tried

%macro keeplist;
%if month(&report_date) = 6 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a18;
%if month(&report_date) = 5 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a17;
%if month(&report_date) = 4 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a16;
%mend keeplist;

%keeplist;

proc sql; create table test (keep= &varlist2) as 
select *
from items a 
left outer join history b	
on a.ID = b.ID
quit;

But I get this;

 

 

ERROR: Required operator not found in expression: month(&report_date) = 6.

 

Another attempt using %LET does allow me to specify the correct columns, but I need to make this conditional on the month.

%let keeplist = &a01 &a02 -- &a13 &a14 -- &a16;

proc sql; create table test (keep= &keeplist) as
select *
from items a 
left outer join history b 
on a.ID = b.ID
quit;

 Can anyone advise how best to do this? Thanks in advance

7 REPLIES 7
Amir
PROC Star

Hi,

 

Can &report_date be in any of the 18 months?

 

If so, what should the keep list be if it is in the first month and what should the keep list be if it is in the last month?

 

If not, then what range of months can &report_date be in and could it be in a different year compared to the most recent month?

 

 

Regards,

Amir.

catmad
Calcite | Level 5
No - the report date is 'today' and all of the data relates to previous months. So, a report for today (12th July) would include all months between June 2018 and Jan2017 (18 months)
Amir
PROC Star

Hi,

 

So would the keep list always have 18 variables, e.g., for today col_jan17,...,col_jun18?

 

Regards,

Amir.

catmad
Calcite | Level 5

I have got something to work, but it may not be the most efficient method !

data _null_;
if month(&report_date) = 1   and year(&report_date) = 2017 then call symput('k01', "&a01");					/* In Jan, keep Dec */
if month(&report_date) = 2   and year(&report_date) = 2017 then call symput('k01', "&a01 &a02");			/* In Feb, keep Dec & Jan */
if month(&report_date) = 3   and year(&report_date) = 2017 then call symput('k01', "&a01 &a02 -- &a03");	/* In Mar, keep Dec, Jan & Feb */
etc etc

data with_history (keep=&k01);
set history;
run;
Quentin
Super User

Hi,

 

To your original question/error, the below code errors because the MONTH() function is not part of the macro language, it's part of the data step language:

%macro keeplist;
%if month(&report_date) = 6 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a18;
%if month(&report_date) = 5 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a17;
%if month(&report_date) = 4 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a16;
%mend keeplist;

Luckily, the macro language has a function, %sysfunc, which calls functions from the data step language.  So the below will work.

 

%macro keeplist;
%global varlist2;
%if %sysfunc(month(&report_date)) = 6 %then %let varlist2 = &a01 &a02 -- &a13 &a14 -- &a18;
...
%mend keeplist;

Note the added %global statement, if this were not there VARLIST2 would be created as a local macro variable.

 

But I would not recommend this approach. It seems like if you transpose your data, so that instead of having one column for each month you have one record for each month, it would become much easier.

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Amir
PROC Star

Hi,

 

The following data step just creates a macro variable for the keep list, not individual macro variables for each column (which should be easy enough to do; just ask if also required):

 

%let report_date = '15May2018'd;

data _null_;
   length keep_list $ 200;

   do i = -18 to -1;
      keep_list = cat(strip(keep_list), ' ', cat('col_', put(intnx('month',&report_date,i), monyy5.)));
   end;

   call symput('keep_list',keep_list);
run;

%put keep_list = &keep_list;

 

 

Regards,

Amir.

Astounding
PROC Star

Most likely, you designed the process to be difficult by your choice of column names.  The problem would become much easier to solve (I think) if you were to get rid of these names:

 

col_Dec16 col_Jan17 ColFeb17

 

Use these names instead:

 

col_201612 col_201701 col_201702

 

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 1301 views
  • 0 likes
  • 4 in conversation