BookmarkSubscribeRSS Feed
ajatshatru
Fluorite | Level 6

Hi I have data sets as follows : 

DATA_SET_202202 (Records for month Feb, 2022)

DATA_SET_202203 (Records for month Mar, 2022) 

and so on 

 

I want to append all the data sets in a single table such that records from DATA_SET_202202 are first followed by _202203 

and so on 

 

I am using the below MACRO for this  : 

 

%MACRO JOIN; 

 

%LET DD = '202202';

%DO COUNT = 0 %TO 4 ;  /*FOR TEST RUN*/ 

 

%LET DD_DATE = INPUT(&DD.,YYMMN6.); 

 

DATA _NULL_ ;

CALL SYMPUTX('BASEMON&COUNT', PUT(INTNX('MONTH',&DD_DATE.,&COUNT.),YYMMN6.));

RUN; 

 

%PUT BASEMON&COUNT:&&BASEMON&COUNT;

 

%IF &COUNT. = 0 %THEN %DO ;

DATA TEST;

SET DATA_SET_&&BASEMON&COUNT.;

RUN; 

%END;

 

%ELSE %D0;

PROC APPEND BASE =TEST DATA=DATA_SET_&&BASEMON&COUNT.;

RUN;

%END;

%END;

%MEND; 

 

In this i am getting error that my variable basemon&count itself is not getting created. Can anyone please suggest 

11 REPLIES 11
PaigeMiller
Diamond | Level 26

Why a macro at all?

 

Why not this:

 

data want; 
    set data_set_2022: ;
run;
--
Paige Miller
ajatshatru
Fluorite | Level 6

 I do not have just a single data_set_2022. I have many monthly tables like this which i need to append in a single data set. So i am using a macro and a loop 

Tom
Super User Tom
Super User

@ajatshatru wrote:

 I do not have just a single data_set_2022. I have many monthly tables like this which i need to append in a single data set. So i am using a macro and a loop 


It was obvious from your question that you had multiple datasets.  None of the answered submitted so far assumed otherwise.

yabwon
Onyx | Level 15

Read this: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lestmtsref/p00hxg3x8lwivcn1f0e9axziw57y.htm#p...

so you will understand that this is what you need.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



PaigeMiller
Diamond | Level 26

@ajatshatru wrote:

 I do not have just a single data_set_2022. I have many monthly tables like this which i need to append in a single data set. So i am using a macro and a loop 


I did not write code for the case where you had a single data set. The code I wrote appends all data sets whose name BEGINS WITH data_set_2022.

--
Paige Miller
Reeza
Super User

Instead of listing them manually use shortcut lists.

Here is a reference that illustrates how to refer to variables and datasets in a short cut list:
https://blogs.sas.com/content/iml/2018/05/29/6-easy-ways-to-specify-a-list-of-variables-in-sas.html

 

Additionally you can use INDSNAME option to store the source data set name and then sort by that variable if you want a specific order.

 

data want;
length source dsn $32.;
set data_set_2022: indsname=source; *will append any datasets that start with the prefix;
dsn = source;
run;

@ajatshatru wrote:

Hi I have data sets as follows : 

DATA_SET_202202 (Records for month Feb, 2022)

DATA_SET_202203 (Records for month Mar, 2022) 

and so on 

 

I want to append all the data sets in a single table such that records from DATA_SET_202202 are first followed by _202203 

and so on 

 

I am using the below MACRO for this  : 

 

%MACRO JOIN; 

 

%LET DD = '202202';

%DO COUNT = 0 %TO 4 ;  /*FOR TEST RUN*/ 

 

%LET DD_DATE = INPUT(&DD.,YYMMN6.); 

 

DATA _NULL_ ;

CALL SYMPUTX('BASEMON&COUNT', PUT(INTNX('MONTH',&DD_DATE.,&COUNT.),YYMMN6.));

RUN; 

 

%PUT BASEMON&COUNT:&&BASEMON&COUNT;

 

%IF &COUNT. = 0 %THEN %DO ;

DATA TEST;

SET DATA_SET_&&BASEMON&COUNT.;

RUN; 

%END;

 

%ELSE %D0;

PROC APPEND BASE =TEST DATA=DATA_SET_&&BASEMON&COUNT.;

RUN;

%END;

%END;

%MEND; 

 

In this i am getting error that my variable basemon&count itself is not getting created. Can anyone please suggest 


 

Tom
Super User Tom
Super User

Depending on your actual needs you might look at using dataset lists.

You can use prefix based lists by using a colon.  So if you want to combine any dataset from 2022 it might look like this.

data test;
  set DATA_SET_2022: ;
run;

Or you can use numeric sequences using hyphen.  So if you want March 2022 to August 2023 you might use this:

data test;
  set DATA_SET_202203 - DATA_SET_202212 DATA_SET_202301 - DATA_SET_202308 ;
run;

You could make your macro simpler by just generating the list of dataset names.

%macro dslist(prefix,start,end);
%local offset;
%do offset=0 %to %sysfunc(intck(month,&start,&end));
 &prefix.%sysfunc(intnx(month,&start,&offset),yymmn6.)
%end;
%mend dslist;

so that you could call it in the middle of a statement, like the SET statement.   

data test;
  set %dslist(data_set_,'01SEP2022'd,'01MAR2023'd) ;
run;

 

FreelanceReinh
Jade | Level 19

You could even use the NODSNFERR system option in conjunction with a dataset list spanning several years:

options nodsnferr;

data test;
set data_set_202202-data_set_202403;
run;

options dsnferr;
yabwon
Onyx | Level 15

I would add one more "option": 

options nodsnferr;

data test;
  set data_set_: INDSNAME=inds;
  obsFromDataSet=inds;
  dataPeriod = input(scan(inds,-1,"_"),yymmdd10.);
  format dataPeriod yymmdd10.;
run;

options dsnferr;

The INDSNAME= gets you info about dataset from which a given observation is from. 

 

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



s_lassen
Meteorite | Level 14

You have had a few suggestions of various ways to simplify your code using wildcards etc. - but if you need to do the append with a specific number of increasing dates, your own method may be the right way to do it.

 

The problem you have with the BASEMON&count variable is, as @Kurt_Bremser remarked, that you put the macro variable name in single quotes, like 'BASEMON&COUNT', this means the data step will try to put data into a macro variable named BASEMON&COUNT and not e.g. BASEMON1 (no resolution of the COUNT variable, so the macro variable name will not be syntactically correct).

 

But I would probably write the macro somewhat differently, a first version would look like this:

%MACRO JOIN; 
%local StartMonth NoofMonths OutData Date Month DD_Month;
%LET StartMonth = 202202; /* a better and more descriptive name than DD */
%let NoofMonths=5; /* we do 1 to 5 and not 0 to 4, is intuitively easier */
%let OutData=TEST;
/* now convert StartMonth to e.g. 01FEB2022 */
%let Date=%sysfunc(input(&StartMonth,YYMMN6.),date9.);

/* Delete output, if exists */
Proc delete data=&outdata;run;

/* and then we loop, proc APPEND will create a new table if BASE does not exist */
%do Month=1 %to &NoofMonths;
  %let DD_Month=%sysfunc(put("&Date"d,YYMMN6.));
  PROC APPEND BASE =&outdata DATA=DATA_SET_&DD_Month;
  RUN;
  %let Date=%sysfunc(intnx(MONTH,"&Date"d,1,B),date9.);
  %end;

%MEND; 

You could also make the DATE macro variable a numeric variable, but I prefer using the DATE9. format, which makes SYMBOLGEN output much easier to understand.

 

When running for real, you will want to use parameters for your macro, e.g.

%MACRO JOIN(StartMonth,NoofMonths,OutData); 
%local Date Month DD_Month;
/* now convert StartMonth to e.g. 01FEB2022 */
%let Date=%sysfunc(input(&StartMonth,YYMMN6.),date9.);

/* Delete output, if exists */
Proc delete data=&outdata;run;

/* and then we loop, proc APPEND will create a new table if BASE does not exist */
%do Month=1 %to &NoofMonths;
  %let DD_Month=%sysfunc(put("&Date"d,YYMMN6.));
  PROC APPEND BASE =&outdata DATA=DATA_SET_&DD_Month;
  RUN;
  %let Date=%sysfunc(intnx(MONTH,"&Date"d,1),date9.);
  %end;

%MEND; 

So you can call it like

%join(202202,5,TEST);

 

 

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
  • 11 replies
  • 519 views
  • 7 likes
  • 8 in conversation