Date: Thu, 30 Oct 1997 08:58:30 -0800
Reply-To: "kmself@ix.netcom.com" <kmself@ix.netcom.com>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: "Karsten M. Self" <kmself@IX.NETCOM.COM>
Organization: Self Analysis
Subject: Re: How to JOIN without SQL
Content-Type: text/plain; charset="us-ascii"
On Wednesday, October 29, 1997 11:24 PM, M. Esther Colwell
[SMTP:mec7@ITSA.UCSF.EDU] wrote:
> Another alternative is to access the SASHELP.VTABLE and put
> the number of obs. in a macro variable, e.g.
>
> Data _null_;
> set sashelp.vtable;
> where libname = 'Yourlibrary' and memname = 'Yourdata';
> call symput('numobs', put(nobs,8.));
> run;
Yes, or the new ATTRN(dsid, 'obs') data step function, or the %SYSFUNC
version of the same, or a data step beforehand which counts _N_ and
outputs a macrovariable at end-of-file (ugly, but I've seen it done).
Many ways to skin a cat.
Simplicity would suggest using the method requiring the least additional
code, offering the greatest efficiency, and most clearly demonstrating to
the next poor slob to come along and maintain my code, _what_ precisely
(or imprecisely) I had in mind when I did whatever I did.
From a stylistic/maintenance perspective, I find the idea of creating an
additional, unnecessary, program step and macro variable (either of which
might get lost or abused at some future modification of the code) a very
poor alternative to a two-word change to a set statement in the data step
which utilizes the result.
If I had to find the number of observations in a dataset I was not
otherwise accessing in a DATA step, I would use the ATTRN function, with
the appropriate OPEN and CLOSE commands. For a PROC or purposes of macro
looping, %SYSFUNC(ATTRN(...))) to feed the value directly into an
expression:
%let rc=%sysfunc(open(mydata));
%do iObs= 1 %to %sysfunc(attrn(&rc,obs));
/* something involving by-record processing.
/* ...though God knows why in Macro */
%end; /* iObs processing */
%let rc=%sysfunc(close(&rc));
%if &rc ne 0 %then
%do;
/* error processing */
%end;
I stand by my previous recommendation of a single SET statement with
POINT= access and the NOBS= option.
> At 10:30 PM 10/29/97 -0800, you wrote:
> >To join the fray, I suspect that Tim's suggestion could be simplified
> >by
> >eliminating the first SET statement on ZIPFILE and moving the NOBS=
> >option
> >to the second set statement. NOBS= is calculated at compile time, not
> >execute time (I thin, very much, without actually being able to test
> >it).
> >
> >To prove or refute, try the following, which never _executes_ the set
> >statement. I believe it should work as intended:
> >
> > /* With apologies to the current thread on style */
> > data in; do i= 1 to 100; output; end; run;
> >
> > data _null_;
> > put nobs=;
> > stop;
> > set in nobs= nobs;
> > run;
> >
> >I believe you will have
> > nobs= 100
> >
> >...output to your log.
> >
> >See below for appropriate modifications.
> >
> >
> >On Wednesday, October 29, 1997 10:46 AM, Tim Berryhill 3rd time
> >[SMTP:TWB2%Rates%FAR@bangate.pge.com] wrote:
> >> Esther, I think your friend is concerned about a problem which does
> >> not
> >> apply.
> >> She would not actually need a STOP statement. SAS does not stop a
> >> data
> >> step for
> >> reading the last obs using random access, so the reads to ZIPFILE
> >> would
> >> not stop
> >> the step. Just to be cute I might avoid coding the number of obs in
> >> ZIPFILE:
> >>
> >> DATA DISTFILE;
> >> /* if 0 then set zipfile nobs=maxobs; /* commented */
> >> SET HOSPFILE;
> >> DO OBSNUM=1 TO maxobs;
> >> SET ZIPFILE POINT=OBSNUM nobs= maxobs; /* nobs added */
> >> DISTANCE = .......................
> >> output;
> >> end;
> >> run;
> >>
> >> Tim Berryhill - Contract Programmer and General Wizard
> >> TWB2@PGE.COM or http://www.aartwolf.com/twb.html
> >
> >Karsten M. Self (kmself@ix.netcom.com)
Karsten M. Self (kmself@ix.netcom.com)
What part of "gestalt" don't you understand?
(Welchen Teil von <<Gestalt>> verstehn Sie nicht?)
|