BookmarkSubscribeRSS Feed
deleted_user
Not applicable
My code simplified:

%macro test;
%do i=1 %to 3;
data OUT1 OUT2 OUT3;
set IN;
select(&i);
when(1) do; if x='A' then count1+1; output out1; end;
when(2) do; if x='B' then count2+1; output out2; end;
when(3) do; if x='C' then count3+1; output out3; end;
otherwise;
run;
%end;
%mend;

x has all three values A, B and C, in data set IN.

The only counting is done when i=3, and I get the number of records with x='C' in data set IN, and I get that correctly in OUT3.

OUT1 and OUT2 have 0 observations.

This is probably a very simple mistake I've made, but I can't find it.

Susan
7 REPLIES 7
SushilNayak
Obsidian | Level 7
Hey Susan,
the do loop is making the datasets out1 out2 out3 created for i=1 for i=2 /3 the datasets are replaced, thats why the data1 /2 is coming out as 0
for i=1
data OUT1 OUT2 OUT3;
set IN;
select(1);
when(1) do; if x='A' then count1+1; output out1; end;
when(2) do; if x='B' then count2+1; output out2; end;
when(3) do; if x='C' then count3+1; output out3; end;
otherwise;
end;
for i=2
data OUT1 OUT2 OUT3;
set IN;
select(2);
when(1) do; if x='A' then count1+1; output out1; end;
when(2) do; if x='B' then count2+1; output out2; end;
when(3) do; if x='C' then count3+1; output out3; end;
otherwise;
end;

for i=3
data OUT1 OUT2 OUT3;
set IN;
select(3);
when(1) do; if x='A' then count1+1; output out1; end;
when(2) do; if x='B' then count2+1; output out2; end;
when(3) do; if x='C' then count3+1; output out3; end;
otherwise;
end;

As you said the that the only counting is done when i=3, and you get the number of records with x='C' in data set IN, and I get that correctly in OUT3.
OUT1 and OUT2 have 0 observations. This is because the dataset OUT1/2 is getting reused by the last do loop (i=3). thats why the count1/2 =0
Doc_Duke
Rhodochrosite | Level 12
Susan,

Sushil nailed the 'why' part of your question. You should be able to see the behavior in the SAS log. The DATA step was run three times. The first time it would have shown the proper number of observations for OUT1, the second for OUT2, and the third, as you saw, for OUT3. When trying to debug problems like this, using OPTIONS MPRINT; and looking carefully at the log can really help.

Doc
Cynthia_sas
SAS Super FREQ
Hi:
Another good rule is that working with SAS macro programs, you should have a working SAS program to start from -- so you know where your macro variables go and so you know what output you will get given your input.

What confuses me about your program is what the desired results will be. You want 3 tables, OUT1, OUT2 and OUT3. you are creating a cumulative "count" variable -- for every value of X: COUNT1, COUNT2 and COUNT3 -- but you're not keeping X and COUNT1 in OUT1, X and COUNT2 in OUT2, etc. So I'm not sure what you want in your final output.

cynthia

Here's a question. Given this data, what would you expect to see in OUT1 for example???
[pre]
X NUM
A 111
B 222
C 333
A 444
B 555
C 666

***********
Possible desired results OUT1:
X NUM COUNT1
A 111 1
A 444 2
[/pre]
deleted_user
Not applicable
Possible desired results OUT1:
X NUM COUNT1
A 111 1
A 444 2

Yes, that's what I wanted.

**************************************

DATA OUT&i.;

Susan
Cynthia_sas
SAS Super FREQ
I guess, then, that I don't understand where the need for the macro do loop comes in. A select/when test on X get you those results without using a macro program. I can understand how you might want to run this program more times or make it more generic, but I think that something like this will give you the desired results.

cynthia
[pre]
data IN;
infile datalines;
input x $ num;
return;
datalines;
A 111
A 444
B 222
B 555
C 333
C 666
;
run;

data OUT1(keep=x num count1)
OUT2(keep=x num count2)
OUT3(keep=x num count3);
set IN end=eof;
select(x);
when('A') do; count1+1; output out1; end;
when('B') do; count2+1; output out2; end;
when('C') do; count3+1; output out3; end;
otherwise;
end;
run;

proc print data=out1;
title 'out1';
run;

proc print data=out2;
title 'out2';
run;

proc print data=out3;
title 'out3';
run;
[/pre]
deleted_user
Not applicable
As I said: My code is simplified.

And it's very much simplified.

When I have a question I try to narrow the description of the real case, and concentrate on the main issue.
Cynthia_sas
SAS Super FREQ
Hi:
I know what you mean. Sometimes macro programs can get very complicated, very fast.

My overall approach would be somewhat different, rather than hard-code OUT1, OUT2 and OUT3 or A, B and C in the DATA step, I'd let macro logic take care of the values of X based on the values of &I. I'd probably use an approach like shown below, which would allow me to increase the size of the %DO loop without changing the data set names or the SELECT.

Of course, you may have considered this design already and rejected it because of the other programming you need to do, but I thought this possibility worth posting in case other folks have a simlar question and only need the simpler approach.

cynthia
[pre]
data IN;
infile datalines;
input x $ num;
return;
datalines;
A 111
A 444
B 222
B 555
C 333
C 666
;
run;

%macro test;
%do i=1 %to 3;

%if &i = 1 %then %do; %let want=A; %end;
%else %if &i = 2 %then %do; %let want=B; %end;
%else %if &i = 3 %then %do; %let want=C; %end;

data OUT&i;
set IN;
if x = "&want" then do;
count&i + 1;
output out&i;
end;
run;

proc print data=out&i;
title "Out&i Data and Count Test for X: &want";
run;

%end;
%mend;

options mprint symbolgen;
%test;
[/pre]

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
  • 7 replies
  • 997 views
  • 0 likes
  • 4 in conversation