turn on suggestions

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

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- Arithmetic calculation in macro

Topic Options

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

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2018 11:45 PM

I'd like to compute &rate across the range of variable 'scale' takes. Data 'want' then would have rate01 thru rate2 across all scales. But my code below produces only one column for a single rate.

Any idea why my code fails to create &rate for whole range?

`&rate=(agerisk*&scale)/tot_pop;`

```
data temp;
input tot_pop agerisk;
datalines;
15286 0.055
57522 0.217
28017 0.066
21669 0.064
17853 0.071
17325 0.080
19893 0.081
22637 0.072
22788 0.062
21019 0.048
17881 0.038
11968 0.034
8676 0.031
21670 0.060
;
%symdel;
%macro models(rate,scale);
data want; set temp;
&rate=(agerisk*&scale)/tot_pop;
run;
%mend models;
%models(rate01,0.1);
%models(rate02,0.2);
%models(rate03,0.3);
%models(rate04,0.4);
%models(rate05,0.5);
%models(rate06,0.6);
%models(rate07,0.7);
%models(rate08,0.8);
%models(rate09,0.9);
%models(rate1,1);
%models(rate11,1.1);
%models(rate12,1.2);
%models(rate13,1.3);
%models(rate14,1.4);
%models(rate15,1.5);
%models(rate16,1.6);
%models(rate17,1.7);
%models(rate18,1.8);
%models(rate19,1.9);
%models(rate2,2);
```

Accepted Solutions

Solution

02-10-2018
12:32 AM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Cruise

02-10-2018 12:14 AM

Because you always start from the TEMP data set so no previous changes are maintained.

Basically you overwrite your results with each iteration, so you need to reuse the data set in this case if you want to include the previous results.

All Replies

Solution

02-10-2018
12:32 AM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Cruise

02-10-2018 12:14 AM

Because you always start from the TEMP data set so no previous changes are maintained.

Basically you overwrite your results with each iteration, so you need to reuse the data set in this case if you want to include the previous results.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Reeza

02-10-2018 12:20 AM

data temp; set temp;

right? so that temp is used repeatedly?

right? so that temp is used repeatedly?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Cruise

02-10-2018 12:27 AM

Try it

Cruise wrote:

data temp; set temp;

right? so that temp is used repeatedly?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Reeza

02-10-2018 12:32 AM

worked out! Thanks Reeza.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Cruise

02-10-2018 12:56 AM

Since your rates are just .1,.2.3,... you could easily do this without macro code.

```
data want ;
set temp;
array rate rate01-rate20;
do i=1 to dim(rate);
rate(i) = (agerisk*(i/10))/tot_pop;
end;
drop i;
run;
```

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-10-2018 02:30 PM

What if rate01-rate20 wasn't known? I eventually would use more granular integers where I have no idea of n points in the range?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Cruise

02-10-2018 02:42 PM

Use a separate array for the list of "scale" values.

So if I had 5 "scale" values I could use a program like this to calculate 5 new "rate" variables.

```
data want ;
set temp;
array rate (5) ;
array scale (5) _temporary_ (.1 .25 .5 1 1.5) ;
do i=1 to dim(rate);
rate(i) = (agerisk*scale(i))/tot_pop;
end;
drop i;
run;
```

You could make it dynamic by putting the list of values into a macro variable and then using COUNTW() to find out how many there were.

```
%let scales=.1 .25 .5 1 1.5;
%let n=%sysfunc(countw(&scales,%str( )));
```

So then use the macro variables to define the arrays.

```
array rate (&n) ;
array scale (&n) _temporary_ (&scales) ;
```