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