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

Level 2 Practice: Using a %DO %UNTIL Loop

m104p11.sas

Modify the Storms macro to accept a space-separated list of years. Use a %DO %UNTIL loop and the %SCAN macro function to generate a report for each year in the list. 

 

here is the code I have executed that is giving an error message (shown below the code):

 

%macro storms(year);
%let i=1;
%let yr=%scan(&year, &i);
%do %Until (&yr eq) ;
title "&yr Storms";
proc means data=mc1.storm_final n min mean max maxdec=0;
var MaxWindMPH MinPressure;
where season=&yr;
run;

%let i = %eval(&i+1);
%let yr=%scan(&year, &i);
%end;
title;
%mend storms;

%storms

 

 

hmlong25_0-1741620139059.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Your code is truncated perhaps??

You defined the macro STORMS to accept an input parameter.  But you did not pass it any value for the parameter in your call to the macro.  Try either one of these macro calls instead.

%storms(2019 2020)
%storms(year=2019 2020)

Remember that you can pass values to a macro by NAME even for parameters that you defined to allow the values to passed by position.

 

Also your code is NOT expecting a space delimited list.  Instead it is expecting a list that is delimited by any of the default delimiters that the %SCAN() function uses.

 

If you use the %SCAN function with only two arguments, then the default delimiters depend on whether your computer uses ASCII or EBCDIC characters.

  • If your computer uses ASCII characters, then the default delimiters are as follows:

    blank ! $ % & ( ) * + , - . / ; < ^¦

    In ASCII environments that do not contain the ^ character, the %SCAN function uses the ~ character instead.

  • If your computer uses EBCDIC characters, then the default delimiters are as follows:

    blank ! $ % & ( ) * + , - . / ; < ¬ | ¢¦

To make it use only SPACE as the delimiter update this line (in both places it appears) in your macro definition.

%let yr=%scan(&year, &i, %str( ));

 

 

 

View solution in original post

8 REPLIES 8
SASJedi
Ammonite | Level 13

The first thing I see is that your code does not provide a space-delimited list of years for the macro to work with. If you provide some values like this:

 

%storms(1980 1990 2000 2010)

your macro will generate a report for each year.

 

Check out my Jedi SAS Tricks for SAS Users
PaigeMiller
Diamond | Level 26

Another example of using a macro when you don't need a macro. You can obtain the same without macros, using a BY statement in PROC MEANS. In other words, a terrible question, and the student comes away from this class thinking "When I need to get statistics by year, I can do this via a macro!" which is completely the wrong lesson to learn.

--
Paige Miller
Amir
PROC Star

Hi,

 

To see what the macro is generating you can submit the following line of code before invoking the macro:

 

 

options mprint;

 

 

 

Then you can see if there are any issues with the generated code.

 

Also, if variable season is character then remember to use double quotes around the &yr value in the where statement, i.e.:

 

 

where season="&yr";

 

 

 

If you're still having issues then please share the whole log (with the mprint option) by copying and then pasting it here using the Insert Code icon "</>".

 

 

Thanks & kind regards,

Amir.

Tom
Super User Tom
Super User

Your code is truncated perhaps??

You defined the macro STORMS to accept an input parameter.  But you did not pass it any value for the parameter in your call to the macro.  Try either one of these macro calls instead.

%storms(2019 2020)
%storms(year=2019 2020)

Remember that you can pass values to a macro by NAME even for parameters that you defined to allow the values to passed by position.

 

Also your code is NOT expecting a space delimited list.  Instead it is expecting a list that is delimited by any of the default delimiters that the %SCAN() function uses.

 

If you use the %SCAN function with only two arguments, then the default delimiters depend on whether your computer uses ASCII or EBCDIC characters.

  • If your computer uses ASCII characters, then the default delimiters are as follows:

    blank ! $ % & ( ) * + , - . / ; < ^¦

    In ASCII environments that do not contain the ^ character, the %SCAN function uses the ~ character instead.

  • If your computer uses EBCDIC characters, then the default delimiters are as follows:

    blank ! $ % & ( ) * + , - . / ; < ¬ | ¢¦

To make it use only SPACE as the delimiter update this line (in both places it appears) in your macro definition.

%let yr=%scan(&year, &i, %str( ));

 

 

 

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 8 replies
  • 1281 views
  • 7 likes
  • 5 in conversation
OSZAR »