BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
djbateman
Lapis Lazuli | Level 10

I have a macro variable that I split up into X number of macro variables, each macro variable storing a number.  I want to sum up those number.  I cannot get the code below to work properly.  Can anyone help me figure out how to use the SUM() function with macro variables?

%macro enrollment(rampdata=);

     %let rampmo=%sysfunc(countw(&rampdata.,'|'));

     %put &rampmo.;

     %do i=1 %to &rampmo.;

          %let ramp&i.=%scan(&rampdata.,&i.,'|');

          %let ramp&i.=%sysfunc(compress(&&ramp&i.));

          %put &&ramp&i.;

     %end;

     %let rampsum=%eval(sum(OF ramp1-ramp&rampmo.));     /* I know this is wrong, and I tried different way here.  Can't figure it out. */

     %put &steadymo.;

%mend enrollment;

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|10|10);

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

The SUM function doesn't exist in macro language.  In general, to use DATA step functions in macro language, you have to apply %SYSFUNC:

%let rampsum = %eval(%sysfunc(sum(of ramp1 - ramp&rampmo.)));

Even this is not a working statement, as the word OF causes trouble for macro language.

Better yet, skip most of the code and shift to:

%let rampsum = %eval(%sysfunc(translate(&rampdata, +, |)));

This will convert all the "|" to "+", then perform the math.

Good luck.

View solution in original post

5 REPLIES 5
Astounding
PROC Star

The SUM function doesn't exist in macro language.  In general, to use DATA step functions in macro language, you have to apply %SYSFUNC:

%let rampsum = %eval(%sysfunc(sum(of ramp1 - ramp&rampmo.)));

Even this is not a working statement, as the word OF causes trouble for macro language.

Better yet, skip most of the code and shift to:

%let rampsum = %eval(%sysfunc(translate(&rampdata, +, |)));

This will convert all the "|" to "+", then perform the math.

Good luck.

Patrick
Opal | Level 21

2 more alternatives:

/* alternative 1 */
%macro enrollment(rampdata=);
  %let rampmo=%sysfunc(countw(&rampdata.,'|'));
  %put &rampmo.;
  %let rampsum=;
  %do i=1 %to &rampmo.;
    %let rampsum=%sysevalf(&rampsum + %scan(&rampdata.,&i.,'|'));
  %end;
  %put rampsum= &rampsum.;
%mend enrollment;

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|9.5|10.5);


/* alternative 2 */
%let rampdata=0|1|2|2|4|4|5|6|8|8|13|9.5|10.5;
%let rampsum2=%sysfunc(sum(%sysfunc(translate(&rampdata,+,|))));
%put rampsum2= &rampsum2;

data_null__
Jade | Level 19

Looks like you are on the road to ruin with a macro like that.  It just seems wrong to me on many levels.  What are you trying to do?

Having said that Patrick almost has it but instead of + is should be comma to accommodate missing values.

 

39 %macro enrollment(rampdata=);

40 %let sum = %sysfunc(sum(%sysfunc(translate(%superQ(rampdata),%str(,),|))));

41 %put NOTE: SUM=∑

42 %mend;

43 %enrollment(rampdata=0|1|2|2|4|4|.|5|6|8|8|13|10|10);

NOTE: SUM=73

Tom
Super User Tom
Super User

I prefer to use spaces as delimiters in strings.  They are easy to type, read and pass as parameters to macros.

Using a space also makes it easy to handle empty strings by adding a default value inside of the call to translate() to prevent syntax errors when the list in the macro variable is empty.

%let list= 1 2 3;

%let sum=%sysfunc(sum(%sysfunc(translate(. &list,%str(,),%str( )))));

%put sum(&list)=∑

sum(1 2 3)=6

%let list= ;

%let sum=%sysfunc(sum(%sysfunc(translate(. &list,%str(,),%str( )))));

%put sum(&list)=∑

sum()=.

Ksharp
Super User

The following is inherited from your code. If you like, but I recommend to use Astounding's code.

%macro enrollment(rampdata=);
     %let rampmo=%sysfunc(countw(&rampdata.,|));
     %put &rampmo.;
     %do i=1 %to &rampmo.;
          %let ramp&i.=%scan(&rampdata.,&i.,|);
          %let ramp&i.=%sysfunc(compress(&&ramp&i.));
        %if &i=1 %then %let list=&ramp1 ;
         %else %let list= &list , &&ramp&i   ;
          %put &&ramp&i.;
     %end;
     %put &list ;
     %let rampsum=%sysfunc(sum( &list ));     /* I know this is wrong, and I tried different way here.  Can't figure it out. */
     %put &rampsum ;
%mend enrollment;

 

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|10|10);













0
1
2
2
4
4
5
6
8
8
13
10
10
0 , 1 , 2 , 2 , 4 , 4 , 5 , 6 , 8 , 8 , 13 , 10 , 10




Ksharp

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 5 replies
  • 21670 views
  • 6 likes
  • 6 in conversation