I have two data sets named want1 want2
Obs | S | C | A | B | MIBC |
1 | 1 | 19.7116 | 3.3106 | 3.17238 | 21.5392 |
2 | 1 | 19.6432 | 2.65416 | 2.13359 | 20.1039 |
Obs | S | C | A | B | MIBC |
1 | 2 | 21.1172 | 2.41381 | 1.82418 | 21.1483 |
---|---|---|---|---|---|
2 | 2 | 26.5052 | 1.41381 | 1.50138 | 25.7135 |
Now i am using following program for my calculation that is working for want1 but giving some error for want2
%macro con;
data final2;
set
%do i = 1 %to 2;
want&i;
if _n_ = round((0.95*2)) then output;
run;
%end;
;
run;
Proc print data=final2;
run;
%mend;
%con;
The log is
NOTE: There were 2 observations read from the data set WORK.WANT1.
NOTE: The data set WORK.FINAL2 has 1 observations and 5 variables.
NOTE: DATA statement used (Total process time):
real time 0.05 seconds
cpu time 0.00 seconds
NOTE: Line generated by the invoked macro "CON".
28766 if _n_ = round((0.95*2)) then output;
--
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: Line generated by the macro variable "I".
28766 want2
-----
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: There were 1 observations read from the data set WORK.FINAL2.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.06 seconds
cpu time 0.00 seconds
Kindly help me in this regard and point out where actually the error is
Regards
Sorry, that code is a bit of a mess. The reason you are getting the error is because of the macro loop, imagine what the code being generated looks like:
%do i = 1 %to 2;
want&i;
if _n_ = round((0.95*2)) then output;
run;
%end;
So set is there, then the first loop occurs:
data final2; set want1.; if _n_=round((0.85*2)) then output; run;
Then the next i loop occurs:
data final2; set want1.; if _n_=round((0.85*2)) then output; run; want2; if _n_=round((0.95*2)) then output; run;
As you can see the second loop has no data final2 or set and so becomes invalid code.
Of course, as is almost always the case, you don't need any of that macro code at all, the semicolon modifier on the dataset name can be used:
data final2;
set want:;
if _n_=round((0.95*2)) then output;
run;
Thank RW9
Actually I want to apply if condition on each of the separate data sets want1 (two obs) and want2 (two obs)
According to your code of semicolon modifier, it actually combine both data sets and then apply if condition on combined data sets (with 4 obs)
So what is the condition, it looks like your using the _n_ automatic obs number, it isn't advised. As for the other part:
data _null_:
do i=1 to 2;
call execute(cats('data final',put(i,1.),'; set want',put(i,1.),'; if _n_=round((0.95*2)) then output; run;'));
end;
run;
Look at the INDSNAME option which allows you to identify the source for an observation when data is appended.
Also, there's the IN option in the SET statement that will identify the source, but that doesn't work well with the colon modifier.
Once you've identified the source you can apply your conditional logic.
data final2;
set want: indsname=source;
input=source;
run;
I cannot tell what you are trying to accomplish with this code. I would be sure to run what you intend without the macro first, then run the macro and verify the output. This might be what you are intending to do but I'm not sure:
%macro con; | |
data final2; | |
%do i = 1 %to 2; | |
set want&i; |
%end;
if _n_ = round((0.95*2)) then output; |
run;
; | |
run; | |
%mend; |
%con;
And really what is the difference between
if _n_ = round((0.95*2)) then
and
If _n_ = 2 then
other than verbosity and almost certainly more cpu operations?
round((0.95*2)) always results in 2, so why bother???
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.
Find more tutorials on the SAS Users YouTube channel.