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

I am new to SAS and need help with macros. How can I create global variables that are outputs of other functions? For example: 

proc univariate data=dsn;
	var AMT;
	output out=mypctl 
                pctlpre=P_ 
		pctlpts= 40, 95;
run;

After I obtain the two values, I want use them for filtering:

data dsn;
	set dsn;
	where 60 < AMT < 7900 
		and DT <= '30Nov2018'd;
run;

I would like to avoid hard coding the values and set them as variables instead. The same applies to the date filter. The hard coded date was obtained as (the maximum date minus 1 year) after I looked up what the maximum date was. I could do this in R by setting something like

UL <- mypctl[1,2]

LL <- mypctl[1,1]

UL_DT <- max(DT) - years(1)

and use them in the data step for filtering. How can I do this in SAS? Even better if I can set those percentiles and the years to substract in the beginning of the program. Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

Same way. Compute the maximum date using PROC MEANS or PROC UNIVARIATE and then include it into the data set via the same method (if _n_=1 then set ...) You would use the INTNX function to find the date one year earlier.

 

proc means data=dsn noprint;
    var amt dt;
    output out=stats p40(amt)=p40 p95(amt)=p95 max(dt)=maxdt;
run;

data dsn1;
    if _n_=1 then set stats;
    set dsn;
    if p40<amt<p95 and dt<intnx('year',maxdt,-1,'s');
run;
--
Paige Miller

View solution in original post

6 REPLIES 6
Reeza
Super User

Merging in data is usually easier than creating global variables.

https://github.com/statgeek/SAS-Tutorials/blob/master/add_average_value_to_dataset.sas

 

Global variables would be macro variables.

UCLA introductory tutorial on macro variables and macros
https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/


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

 


@asasha wrote:

I am new to SAS and need help with macros. How can I create global variables that are outputs of other functions? For example: 

proc univariate data=dsn;
	var AMT;
	output out=mypctl 
                pctlpre=P_ 
		pctlpts= 40, 95;
run;

After I obtain the two values, I want use them for filtering:

data dsn;
	set dsn;
	where 60 < AMT < 7900 
		and DT <= '30Nov2018'd;
run;

I would like to avoid hard coding the values and set them as variables instead. The same applies to the date filter. The hard coded date was obtained as (the maximum date minus 1 year) after I looked up what the maximum date was. I could do this in R by setting something like

UL <- mypctl[1,2]

LL <- mypctl[1,1]

UL_DT <- max(DT) - years(1)

and use them in the data step for filtering. How can I do this in SAS? Even better if I can set those percentiles and the years to substract in the beginning of the program. Thanks!


 

PaigeMiller
Diamond | Level 26

I agree with @Reeza , you don't need macro variables here.

 

data dsn;
    if _n_=1 then set mypctl;
    set dsn;
    where p_40 < amt < p_95 and ...
run;
    

 

--
Paige Miller
asasha
Obsidian | Level 7

Thank you! The latest date in the dataset (maximum) needs to be used to filter out the observations in the past year (keep the records up to one year prior). If the data goes up to 14feb2020 then I want the data up to 14feb2019. How can I do that automatically? 

PaigeMiller
Diamond | Level 26

Same way. Compute the maximum date using PROC MEANS or PROC UNIVARIATE and then include it into the data set via the same method (if _n_=1 then set ...) You would use the INTNX function to find the date one year earlier.

 

proc means data=dsn noprint;
    var amt dt;
    output out=stats p40(amt)=p40 p95(amt)=p95 max(dt)=maxdt;
run;

data dsn1;
    if _n_=1 then set stats;
    set dsn;
    if p40<amt<p95 and dt<intnx('year',maxdt,-1,'s');
run;
--
Paige Miller
Reeza
Super User
proc sql;
create table want as
select *
from ranked_dsn where rank_amt between 8 and 18
having (dt between intnx('year', max(dt), 0, 'b') and max(dt)) or (dt between intnx('year', max(dt), -1, 'b') and intnx('year', max(dt), -1, 's'));
quit;

Make your comparisons relative - untested but hopefully gives you an idea.
Reeza
Super User
BTW if you're trying to group into groups, using PROC RANK would be another option. RANK assigns values to percentile groups.

proc rank data=dsn out=ranked_dsn groups=20;
var amt;
ranks rank_amt;
run;

data want;
set ranked_dsn;
where rank_amt between 8 and 18; *numbers may need tweaking;
run;

To group into 5 percentiles, number of groups = 20, where 0 = 0 to 5th percentile, 1 = 6 -10th percentile, 19 = 95 to 100

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 6 replies
  • 1202 views
  • 1 like
  • 3 in conversation