Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Home
- /
- Programming
- /
- Enterprise Guide
- /
- Macro do loop, but only every fifth loop

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

☑ This topic is **solved**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 04-20-2023 08:20 PM
(748 views)

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

`%if &v = &v / 5 * 5 %then %do;`

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

**Available on demand!**

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

Find more tutorials on the SAS Users YouTube channel.