Date: Fri, 25 Feb 2000 15:11:31 -0500
Reply-To: "Slagle, Paul" <Paul.Slagle@STATPROBE.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Slagle, Paul" <Paul.Slagle@STATPROBE.COM>
Subject: Re: Macro question
Content-Type: text/plain; charset="iso-8859-1"
This may be a little late, but couldn't this just be accomplished with
transpose steps and a datastep?
Proc sort data=urn; by site_id clientid; run;
Proc transpose data=urn;
by site_id clientid; out=tranurn; run;
Data newurn;
Set Tranurn;
_name_ = substr (_name_, 1, 3); run;
Proc transpose data=tranurn;
by site_id clientid;
id _name_; run;
I believe the code should be correct, short of a 'tweak' here and there.
Paul Slagle
-----Original Message-----
From: WHITLOI1 [mailto:WHITLOI1@WESTAT.COM]
Sent: Thursday, February 24, 2000 2:12 PM
To: SAS-L@LISTSERV.VT.EDU
Subject: Re: Macro question
Subject: Macro question
Summary: Good programming is better than macro
Respondent: Ian Whitlock <whitloi1@westat.com>
Jeremy Miller <millerj@CALIB.COM> has written a macro to split a
data set into 45 pieces and now wants to concatenate the pieces.
His first macro is
> %macro datasets;
> %do i=1 %to 45;
> data dat&i(rename=(scr&i=scr res&i=res));
> set urn(keep=site_id clientid scr&i res&i);
> run;
> %end;
> %mend datasets;
His question is how to write the second macro when for two data sets
he has
> data dat3;
> set dat1 dat2;
> if scr=. | res=. then delete;
> run;
There are two simple macro answers to this question, but the
tragedy is that it shouldn't have been done in the first place. No
macro was necessary or desirable.
data result (keep = site_id clientid x scr res);
set urn(keep=site_id clientid scr1-scr45 res1-res45);
array _scr (45) scr1-scr45 ;
array _res (45) res1-res45 ;
do x = 1 to dim ( _scr ) ;
if _scr(x) ^=. and _res(x) ^=. then output ;
end ;
run ;
proc sort data = result ;
by x ;
run ;
The sort is not needed if the order doesn't matter. Then removing X
from the KEEP list would be possible, but at the expense of losing
information. However that information was also lost in the question.
Now let's look at two macro answers.
> %macro datasets;
> %do i=1 %to 45;
> data dat&i(rename=(scr&i=scr res&i=res));
> set urn(keep=site_id clientid scr&i res&i);
if _scr&i ^=. and _res&i ^=. ;
> run;
proc append base = result data = dat&i ;
run ;
> %end;
> %mend datasets;
or
> %macro datasets;
%local dslist ;
> %do i=1 %to 45;
%let dslist = &dslist dat&i ;
> data dat&i(rename=(scr&i=scr res&i=res));
> set urn(keep=site_id clientid scr&i res&i);
> run;
> %end;
> data dat3;
set &dslist ;
> if scr=. | res=. then delete;
> run;
> %mend datasets;
Of course, there are many more answers with and without macro or
arrays; but the real question is, how have we come teach programmers
about SAS macro before they have learned good SAS programming
techniques?
At Westat the answer is that everyone is using SAS macro so new
beginning programmers must learn some macro to be able to read the
the programs that they have to modify. The cost in terms of long
complex programs has never been estimated nor the method even
questioned. Any different, anywhere else?
Ian Whitlock