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;
@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?
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);
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;
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;
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.
@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.
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!
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.