Fluorite | Level 6

## Macro do loop, but only every fifth loop

I have a large number of loops to run and want to save the data every 1000 loops or so.

In the code below, rather than saying %if &v.=5 or &v.=10 or &v=15 or &v.=20, I'd like to say if &v is a multiple of 5. Any suggestions would be greatly appreciated

``````data a1; input id \$ count ;
datalines;
A	1
A	2
A	3
A	4
A	5
A	6
A	7
A	8
A	9
A	10
A	11
A	12
A	13
A	14
A	15
A	16
A	17
A	18
A	19
A	20
;

proc datasets; delete bb;

libname saveme 'f:\temp\saveme';

%macro loop;
%do v=1 %to 20;

data b; set a1; if count=&v.;
count_sq=count**2;

proc append base=bb data=b;

%if &v.=5 or &v.=10 or &v.=15 or &v.=20 %then %do;
%let x=%eval(&v./5);
data saveme.eth_&x.; set bb;
proc datasets; delete bb;
%end;
%end;
%mend loop;
%loop;
run;``````
1 ACCEPTED SOLUTION

Accepted Solutions
Lapis Lazuli | Level 10

## Re: Macro do loop, but only every fifth loop

Since you ask for selecting every fifth loop: 5, 10, 15, 20, ... The last digit is always 0 or 5, it is a very simple mathematical phenomenon.

So you can validate if the last number of &v. in (0 5) or not.

``````%macro loop/minoperator;
%do v=1 %to 20;

data b; set a1; if count=&v.;
count_sq=count**2;

proc append base=bb data=b;

%if %substr(&v.,%length(&v.)) in (0 5) %then %do;
%let x=%eval(&v./5);
data saveme.eth_&x.; set bb;
proc datasets; delete bb;
%end;
%end;
%mend loop;``````

Note: To use in operator in macro, you need to add "`minoperator`" behind you macro definition statement.

6 REPLIES 6
Barite | Level 11

## Re: Macro do loop, but only every fifth loop

I am on a cellphone and dont have SAS. The way this is done crosses pgm languages. Use the modulus of 5. For SAS, that is the mod function. Mod(counter, 5) = 0.
https://github.com/savian-net
PROC Star

## Re: Macro do loop, but only every fifth loop

Take advantage of the fact that macro language performs integer arithmatic, dropping any remainders.  Try:

``%if &v = &v / 5 * 5 %then %do;``
Lapis Lazuli | Level 10

## Re: Macro do loop, but only every fifth loop

Since you ask for selecting every fifth loop: 5, 10, 15, 20, ... The last digit is always 0 or 5, it is a very simple mathematical phenomenon.

So you can validate if the last number of &v. in (0 5) or not.

``````%macro loop/minoperator;
%do v=1 %to 20;

data b; set a1; if count=&v.;
count_sq=count**2;

proc append base=bb data=b;

%if %substr(&v.,%length(&v.)) in (0 5) %then %do;
%let x=%eval(&v./5);
data saveme.eth_&x.; set bb;
proc datasets; delete bb;
%end;
%end;
%mend loop;``````

Note: To use in operator in macro, you need to add "`minoperator`" behind you macro definition statement.

Super User

## Re: Macro do loop, but only every fifth loop

An option that is very useful is the MINOPERATOR, which allows use of the IN comparison, especially when the case might not involve wanting a choice that can be easily derived with numeric manipulation. The option on the macro of MINOPERATOR means the operator is available. If you want to use something other than the default blank for the separator between values you use the MINDELIMITER option.

```%macro loop / minoperator;
%do v=1 %to 20;

data b; set a1; if count=&v.;
count_sq=count**2;

proc append base=bb data=b;

%if &v. in (5 10 15 20) %then %do;
%let x=%eval(&v./5);
data saveme.eth_&x.; set bb;
proc datasets; delete bb;
%end;
%end;
%mend loop;```

STRONG suggestion for future questions: Do not include custom library assignments or use those libraries in the body of the code. We very likely do not have your drives/paths or even same operating systems. Just include the pieces that you really need to demonstrate the issue.

Second suggestion: In macro code always explicitly provide run; and/or quit; (datasets) to terminate the procedures inside the body of a macro. You never know exactly what the code following a given macro might be and leaving procedures like Datasets still running may cause some very interesting debugging situations. Your current macro leaves datasets running.

Obsidian | Level 7

## Re: Macro do loop, but only every fifth loop

Use modulus function, which returns the remainder.

E.g.

when we divide 5 by 5 we get remainder 0. So Mod(5,5)=0 is True.

when we divide 10 by 5 we get remainder 0. So Mod(10,5)=0 is True.

but when we divide 11 by 5 we get remainder 1. So Mod(11,5)=0 is False.

`Mod(&v.,5)=0`

Hope this will resolve your issues.

-Vijay

Fluorite | Level 6

## Re: Macro do loop, but only every fifth loop

Thanks all - very helpful. Was not aware of the minoperator.

Discussion stats
• 6 replies
• 749 views
• 6 likes
• 6 in conversation