DATA Step, Macro, Functions and more

Replacing If then with Macro

Reply
Contributor
Posts: 35

Replacing If then with Macro

Did not see any prior posts for anything this

 

 

rather than using If then to create a new variable cutoff for PROC FREQ, I would like to use a %LET statement so I can eliminate the data step that creates the cutoff value.  

 

DATA grades;
do i = 1 to 100;
id = i;
grade = int(100*ranuni(123)+1);
output;
end;
RUN;

 

DATA grades_output;
set grades;
if grade >= 70 then cutoff = 1; 
if grade <70 then cutoff = 2;
RUN;

 

PROC FORMAT;
value cutofffmt
1 = 'Passsed'
2 = 'Failed';
RUN;

 

PROC FREQ DATA = grades_output;
title 'Grade Distribution When Cutoff = 70';
format cutoff cutofffmt.;
tables cutoff / NOCUM;
RUN;

 

/******************************************************************************************************

Using %let

 

DATA grades_output_macro;
set grades;
RUN;

 

%MACRO Cutoff;
%if grade >= 70 %then cutoff = 1; 
%if grade < 70 %then cutoff = 2;

 

PROC FORMAT;
value cutofffmt
1 = 'Passsed'
2 = 'Failed';
RUN;

 

PROC FREQ DATA = grades_output_macro;
title 'Grade Distribution When Cutoff = 70';
format cutoff cutofffmt.;
tables &cutoff / NOCUM;
%END;

%MEND Cutoff;
RUN;

 

%Cutoff
RUN;

Respected Advisor
Posts: 3,278

Re: Replacing If then with Macro


@RickyS wrote:

Did not see any prior posts for anything this

 

 

rather than using If then to create a new variable cutoff for PROC FREQ, I would like to use a %LET statement so I can eliminate the data step that creates the cutoff value.  



This won't work since PROC FREQ cannot work on the results of the %LET statement, but it can work on data step variables. (I fail to see even why you want to do this)

 

And the data step works, so why bother introducing the unnecessary complications of macros?

--
Paige Miller
Super User
Super User
Posts: 8,279

Re: Replacing If then with Macro

[ Edited ]

These statements are a big problem.

%if grade >= 70 %then cutoff = 1; 
%if grade < 70 %then cutoff = 2;

You are testing whether the letter g sorts after the digit 7 in the ASCII coding for characters.

You might be able to do something like this:

%MACRO Cutoff(dataset,varname,cutoff);
PROC FORMAT;
  value cutofffmt
    &cutoff - high = 'Passed'
    other = 'Failed'
  ;
RUN;

PROC FREQ DATA = &dataset;
  title "&varname Distribution When Cutoff = &cutoff";
  format &varname cutofffmt.;
  tables &varname / NOCUM;
run;

%MEND Cutoff;

You can then call it with your original dataset without making any new variables.

%cutoff(dataset=grades,varname=grade,cutoff=70);

 

Contributor
Posts: 35

Re: Replacing If then with Macro

Appreciate the discussion, put me on a better track, I think this is the solution they are probably looking for.  A let to replace coding a changing grade value in 3 places.  My best guess.

 

%let Cutoff = 70;

DATA grades_output_macro;
set grades;
if grade >= &Cutoff then cutoff = 1;
if grade < &Cutoff then cutoff = 2;
RUN;

 

PROC FORMAT;
value cutofffmt
1 = 'Passsed'
2 = 'Failed';
RUN;

 

PROC FREQ DATA = grades_output_macro;
title 'Grade Distribution When Cutoff = 70';
format cutoff passedfmt.;
tables cutoff / NOCUM;
RUN;

Super User
Posts: 24,012

Re: Replacing If then with Macro

It may help if you explain the business problem to give us some context. 

 

But I suspect what they're trying to do is automate the groups, pass/fail?

 

I would recommend a direct format for that. You can create formats from a data set. 

 

proc format;
value bmi_fmt
low - 18.5 = 'Underweight'
18.5 - 24.9 = 'Normal'
25 - 29.9 = 'Overweight'
30 - high = 'Obese';
run;

 data class;
    	set sashelp.class;
    	length category $20.;
    	bmi = 703*(weight/(height**2));

    	if bmi < 18 then
    		category='Under Weight';
    	else if 18 <= BMI < 25 then
    		category='Normal';
    	else if 25 <= BMI < 30 then
    		category ='Over Weight';
    	else if BMI >=30 then
    		category = 'Obese';
    run;

title 'Results from IF/THEN statements';
proc freq data=class;
table category;
run;

title 'Results from formats';
proc freq data=class;
table bmi;
format bmi bmi_fmt.;
run;

Super User
Super User
Posts: 8,279

Re: Replacing If then with Macro

Switch to using double quotes for your TITLE statement and you can reference the macro variable there also.

title "Grade Distribution When Cutoff = &cutoff";

PS Use the insert code icons in the forum editor when pasting/editing code in the Forum.

image.png

Super User
Posts: 13,941

Re: Replacing If then with Macro


@RickyS wrote:

Appreciate the discussion, put me on a better track, I think this is the solution they are probably looking for.  A let to replace coding a changing grade value in 3 places.  My best guess.

 


Is this an exercise in a training session or somesuch? Otherwise I wonder why someone would be looking for a specific solution.

And if it is a training or test exercise then give us all the conditions and requirements.

Ask a Question
Discussion stats
  • 6 replies
  • 184 views
  • 3 likes
  • 5 in conversation