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

Hi all,

 

 

i have the following data set:

 

ID    year       Cost

 X    2015      100

 X    2016      200

 X    2017     150

Y    2015      30

 Y    2016      70

 Y    2017     400

...

 

 

Now i want separated data tables for each year and tried:

 

%Macro Test;
%do i=2015 %to 2017;
Data Cost_&i;
set in;
If year=&i then output %end;
%MEND Test;

%Test

 

This doesnt work. Could you please help me.

 

Thank you for your effort!

Mike

 

1 ACCEPTED SOLUTION

Accepted Solutions
Jagadishkatam
Amethyst | Level 16

Alternatively with call execute

 

data have;
input ID $   year       Cost;
cards;
 X    2015      100
 X    2016      200
 X    2017     150
Y    2015      30
 Y    2016      70
 Y    2017     400
 ;
        
proc sql;
create table years as select distinct year from have;
quit;

data _null_;
set years;
call execute('data year_'||strip(year)||'; set have; where year='||year||';run;');
run;	
Thanks,
Jag

View solution in original post

7 REPLIES 7
PaigeMiller
Diamond | Level 26

First of all, I feel compelled to mention, as other people do, that separating data like this is inefficient and a poor practice. You'd be better off in most situations keeping the data in one data set and then when it comes time to do analysis, use the BY statement to get analyses for each year.

 

When running macros like this, you want to use OPTIONS MPRINT; before the macro so as to make the macro easier to debug.

 

When asking for help, saying "This doesn't work" really provides no useful information. Showing us the error (the SAS log) is a much more effective way to get help.

 

The most obvious mistake in your code is that you are missing a semi-colon after OUTPUT and also you need a RUN; statement after the OUTPUT; statement.

--
Paige Miller
Kurt_Bremser
Super User

Write the data step for one year (without any macro action) and compare it to what you create with the macro.

 

Hint: there's something small but important missing.

 

hint-hint: use options mlogic mprint;

novinosrin
Tourmaline | Level 20
data have;
input ID $   year       Cost;
cards;
 X    2015      100
 X    2016      200
 X    2017     150
Y    2015      30
 Y    2016      70
 Y    2017     400
 ;



proc sql ;                                                              
  create index year on have (year) ;                      
quit ;                                                                  
                                                                        
data _null_ ;                                                           
  if _n_ = 1 then do ;                                                  
    dcl hash h (ordered:'y') ;                                                     
    h.definekey  ("_n_") ;                                              
    h.definedata ('id','year','cost') ;
    h.definedone () ;                                                   
  end ;                                                                 
  do _n_ = 1 by 1 until (last.year) ;                            
    set have ;                                                          
    by year ;                                                    
    h.add() ;                                                           
  end ;                                                                 
  h.output (dataset: catx ("_", "year", year)) ;          
  h.clear() ;                                                           
run ;     
Jagadishkatam
Amethyst | Level 16

Alternatively with call execute

 

data have;
input ID $   year       Cost;
cards;
 X    2015      100
 X    2016      200
 X    2017     150
Y    2015      30
 Y    2016      70
 Y    2017     400
 ;
        
proc sql;
create table years as select distinct year from have;
quit;

data _null_;
set years;
call execute('data year_'||strip(year)||'; set have; where year='||year||';run;');
run;	
Thanks,
Jag
novinosrin
Tourmaline | Level 20

@Jagadishkatam  Very nice, traditional and simple. I am glad you posted this. Thank you!

Jagadishkatam
Amethyst | Level 16
I am learning from all the legends in this forum including you. I like @novinosrin coding.
Thanks,
Jag
novinosrin
Tourmaline | Level 20

data have;
input ID $   year       Cost;
cards;
 X    2015      100
 X    2016      200
 X    2017     150
Y    2015      30
 Y    2016      70
 Y    2017     400
 ;

proc sql;
select distinct year into :year  separated by ',' 
from have;
quit;
%macro split/parmbuff;
   %let num=1;
   %let dsname=%scan(&syspbuff,&num);
   %do %while(&dsname ne);
      data year_&dsname;
	  set have;
	  where year=&dsname;
	  run;
      %let num=%eval(&num+1);
      %let dsname=%scan(&syspbuff,&num);
   %end;
%mend split;

%split(&year)

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 1682 views
  • 3 likes
  • 5 in conversation