BookmarkSubscribeRSS Feed
RickyS
Quartz | Level 8

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;

6 REPLIES 6
PaigeMiller
Diamond | Level 26

@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
Tom
Super User Tom
Super User

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);

 

RickyS
Quartz | Level 8

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;

Reeza
Super User

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;

Tom
Super User Tom
Super User

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

ballardw
Super User

@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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 1182 views
  • 3 likes
  • 5 in conversation