BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
saipriya92
Calcite | Level 5

Hi there, 

 

1. I am trying to run the same exact code twice for two datasets and have tried creating a macros for it. Could you maybe tell me if i can do this like this or some-other way ?

 

2. Also how can I see how my macros is processing in the log. Is it the mprint option ? If yes how to use it in this code ?

 

Here's my code

%macro printit (data1=,data2=,data3=,data4=) ;
	
	proc print data=&data1.;
		title &data1.;
	run ;
	proc print data=&data2.;
		title &data2.;
	run ;
		proc print data=&data3.;
		title &data3.;
	run ;
	proc print data=&data4.;
		title &data4.;
	run ;
	
%mend printit ;

%printit (	data1=sasuser.sample1_drugs, 
			data2= sasuser.sample1_step1, 
			data3=sasuser.sample1_step2, 
			data4=sasuser.sample2_drugs) ;

%macro datasets (dataset1=, dataset2=,) ;
			
proc sort data=&dataset1. out=sorted_&dataset1.;
	by ptid drug ;
run ;

proc sort data=&dataset2. out=sorted_&dataset2.;
	by ptid drug;
run ; 

data step1_&dataset1.;
	set sorted_&dataset1. ;
	by ptid drug ;
	if first.drug then gap=0;
	format lag_date date9. ;
	lag_date= lag(drug_dt);
	if drug_dt-lag_date >=60 /*and first.ptid=0*/ then gap + 1;
run ;

proc sql;
	create table step1_final as 
	select ptid, drug, min(drug_dt) as stdt format=date9. ,max(drug_dt) as enddt format=date9. 	
	from step1_1 
	group by ptid, drug, gap ;
quit ;

/* STEP 2 */

data all_days;
  set step1_final;
  do date=stdt to enddt;
    output;
    end;
  drop stdt enddt;
run;

proc sort data=all_days out=all_days_sorted;
  by ptid date;
run;

data all_days2;
  do until(last.date);
    set all_days_sorted;
    by ptid date;
    length regimen $200;
    call catx('+',regimen,drug);
    end;
run;

data all_days3;
  set all_days2;
  by ptid date; 
  diff=dif(date);
  output;
  if not first.ptid and diff>1 then do;
    regimen='BLANK';
    do date=date-diff+1 to date-1;
      output;
      end;
    end;
run;

proc sort data=all_days3 out=all_days3_sorted;
  by ptid date;
run;

data step2_final;
  do until(last.regimen);
    set all_days3_sorted;
    by ptid regimen notsorted;
    if first.regimen then
      stdt=date;
    end;
  enddt=date;
  format stdt enddt date9.;
  keep ptid regimen stdt enddt;
run;

%mend datasets;
 
%datasets (dataset1=sasuser.sample1_drugs, dataset2=sasuser.sample2_drugs) ;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

You're not generalizing your macros enough. 

 

This:

 

%macro printit (data1=,data2=,data3=,data4=) ;
	
	proc print data=&data1.;
		title &data1.;
	run ;
	proc print data=&data2.;
		title &data2.;
	run ;
		proc print data=&data3.;
		title &data3.;
	run ;
	proc print data=&data4.;
		title &data4.;
	run ;
	
%mend printit ;

%printit (	data1=sasuser.sample1_drugs, 
			data2= sasuser.sample1_step1, 
			data3=sasuser.sample1_step2, 
			data4=sasuser.sample2_drugs) ;

Should be:

 

%macro printit (dsn=) ;
	
	proc print data=&dsn.;
		title &dsn.;
	run ;

	
%mend printit ;

%printit (dsn=sasuser.sample1_drugs);
%printit(dsn=sasuser.sample1_step1);
%printit(dsn=sasuser.sample1_step2);
%printit(dsn=sasuser.sample2_drugs);

However, this doesn't really save you much. You use macro's when you need to generalize a program to other data sets, ie you write a program that prepares summary statistics and you want to run it against different data sets or when you need to do the same thing multiple times and the number of times is greater than 3 in general. 

 

Here are some macro references that may be helpful.

 

UCLA introductory tutorial on macro variables and macros

https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/

Tutorial on converting a working program to a macro

This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

Examples of common macro usage

https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

 

View solution in original post

6 REPLIES 6
PaigeMiller
Diamond | Level 26

@saipriya92 wrote:

Hi there, 

 

1. I am trying to run the same exact code twice for two datasets and have tried creating a macros for it. Could you maybe tell me if i can do this like this or some-other way ?

 

2. Also how can I see how my macros is processing in the log. Is it the mprint option ? If yes how to use it in this code ?

  1. Your code looks like it should work. Did you actually try running the code? Does it work? Do you get errors?
  2. Yes, use the MPRINT option.

Comment: your %PRINTIT macro doesn't seem like it saves you any effort, I don't see what you have gained by turning this into a macro. Do you want a macro that prints an arbitrary number of data sets, sometimes you might have 1 data set and sometimes you might have 4 and sometimes you might have 32??

--
Paige Miller
saipriya92
Calcite | Level 5

Tjhe code works, but I dont see a point of using macros when i have to rewrite each step for each dataset. I want to create a macros wherein i can mention the parameters and write the code only once. For instance for the printit macros, there is no point of me creating it since I am still writing the code for each dataset. 

PaigeMiller
Diamond | Level 26

@saipriya92 wrote:

Tjhe code works, but I dont see a point of using macros when i have to rewrite each step for each dataset. I want to create a macros wherein i can mention the parameters and write the code only once. For instance for the printit macros, there is no point of me creating it since I am still writing the code for each dataset. 


Well, that probably should have been stated clearly in your original question, I thought you were asking if the code was correct.

 

How about this:

 

%macro printit2(datasets=);
/* The data set names in &datasets should be separated by a blank */
%do i=1 %to &sysfunc(countw(&datasets));
    %let thisdataset=%scan(&datasets,&i,%str( ));
    proc print data=&thisdataset;
    run;
%end;
%mend;
%macro printit2(datasets=dataset1 dataset2 sashelp.class sashelp.cars dataset5)
--
Paige Miller
Reeza
Super User

You're not generalizing your macros enough. 

 

This:

 

%macro printit (data1=,data2=,data3=,data4=) ;
	
	proc print data=&data1.;
		title &data1.;
	run ;
	proc print data=&data2.;
		title &data2.;
	run ;
		proc print data=&data3.;
		title &data3.;
	run ;
	proc print data=&data4.;
		title &data4.;
	run ;
	
%mend printit ;

%printit (	data1=sasuser.sample1_drugs, 
			data2= sasuser.sample1_step1, 
			data3=sasuser.sample1_step2, 
			data4=sasuser.sample2_drugs) ;

Should be:

 

%macro printit (dsn=) ;
	
	proc print data=&dsn.;
		title &dsn.;
	run ;

	
%mend printit ;

%printit (dsn=sasuser.sample1_drugs);
%printit(dsn=sasuser.sample1_step1);
%printit(dsn=sasuser.sample1_step2);
%printit(dsn=sasuser.sample2_drugs);

However, this doesn't really save you much. You use macro's when you need to generalize a program to other data sets, ie you write a program that prepares summary statistics and you want to run it against different data sets or when you need to do the same thing multiple times and the number of times is greater than 3 in general. 

 

Here are some macro references that may be helpful.

 

UCLA introductory tutorial on macro variables and macros

https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/

Tutorial on converting a working program to a macro

This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

Examples of common macro usage

https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

 

ballardw
Super User

Are you sure this is what you want?

proc sql;
	create table step1_final as 
	select ptid, drug, min(drug_dt) as stdt format=date9. ,max(drug_dt) as enddt format=date9. 	
	from step1_1 
	group by ptid, drug, gap ;
quit ;

Regardless of the parameters passed into the macro this always uses the same dataset. I suspect that since you went a some minor effort to create step1_&dataset1 just before that proc sql step that perhaps you meant From step1_&dataset1

 

Also, be careful creating names like step1_&dataset1. One issue is that if the length of the &dataset1 text is long enough you may generate an invalid data set name. The other is that this restricts the input parameters to single level data set names.

 

ChrisNZ
Tourmaline | Level 20

1. You could use:

%macro printit (data) ;
  proc print data=&data.;
    title &data.;
  run ;
%mend printit ;

%printit (sasuser.sample1_drugs) ;
%printit (sasuser.sample1_step1) ;
%printit (sasuser.sample1_step2) ; 
%printit (sasuser.sample2_drugs) ;

2. Just add

 

options mprint;

in the code before calling the macro,

 

3. I much prefer using spaces instead of tabs, it helps avoiding the formatting issues you got when pasting your code here.

Try that to see if you like it. I despise that my careful formatting might not be conserved depending on the editor.

Not everyone agrees of course, some people like tabs for reason I cannot understand.

 

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 6 replies
  • 1057 views
  • 2 likes
  • 5 in conversation