Date: Wed, 1 May 2002 20:23:30 -0700
Reply-To: Glenn Heagerty <gheagerty@ADELPHIA.NET>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Glenn Heagerty <gheagerty@ADELPHIA.NET>
Organization: Consumer Solutions
Subject: Re: 3 SAS8.2 Programs with Macros ... to Verify
Content-Type: multipart/alternative;
Hi all,
I had some time the last few days and decided to take a stab improving
the three programs posted with the request. My goal was to break the
aggregation parts into two pieces: a macro to create the summary
variable names and a single data step for each archive to be aggregated.
I post these in case someone might find something interesting or of use.
I also welcome any comments.
The ideal was to be able to produce the same output, but quicker with
more manageable code. I'm pleased with the results so far in that I
processed 6 million plus records (randomly generated) with the known
inputs(like six variables), representing 1000 units in about 2 1/2
minutes. There are about 2,800 variables on the output data set.
Of course the second program below needs to be generalized to handle
both archives and needs to be cleaned up for production, but I haven't
got that far yet. Mark, I hope you can find some benefit in it.
Thanks,
Glenn
/** PROJECT: Consumer Solutions SAS-L Questions
SUBJECT: Census Bureau Housing Unit Aggregation Re-write
DATE : May 1, 2002
BY : Glenn Heagerty, Principal
PROGRAM: CR8LST.SAS (Compiled Stored Macros)
PURPOSE: Generate a list of variables based on the levels of gender,
race, hispanic, and age. This list can be used just like
any other
list of SAS variable names.
Sample names: b_mwwh3034, b_xxxxxxxx
**/
libname uscbmacs '$HOME/consumer_solutions/SAS-L/us_census_bureau';
options mstored sasmstore=uscbmacs;
%macro cr8vlst(part1 = x m f _,
part2 = xx ww bb ai ap ot mu __,
part3 = x h n _,
part4 = xxxx 0004 0509 1014 1519 2024 2529 3034 3539 4044
4549 5054 5559
6064 6569 7074 7579 8084 85up 0017 1864 65up,
pfx=b) / store;
%local part1 part2 part3 part4 pfx dims i j k l;
%let dims=4;
%let i=1;
%let j=1;
%do i=1 %to &dims;
%let j=1;
%let part&i._&j=%scan(&&&part&i,&j,%str( ));
%do %while(&&&part&i._&j ne);
%let j=%eval(&j + 1);
%local part&i._&j;
%let part&i._&j=%scan(&&&part&i,&j,%str( ));
%end;
%local lev&i;
%let lev&i=%eval(&j - 1);
%end;
%let i=1;
%let j=1;
%let k=1;
%let l=1;
%do i=1 %to &lev1;
%do j=1 %to &lev2;
%do k=1 %to &lev3;
%do l=1 %to &lev4;
&pfx._&&&part1_&i.&&&part2_&j.&&&part3_&k.&&&part4_&l
%end;
%end;
%end;
%end;
%mend cr8vlst;
/** PROJECT: Consumer Solutions SAS-L Questions
SUBJECT: Census Bureau Housing Unit Aggregation Re-write
DATE : May 1, 2002
BY : Glenn Heagerty, Principal
**/
options mstored sasmstore=uscbmacs;
options merror nomlogic nomprint nomrecall nosymbolgen nosource2;
options compress=no;
%let key=aaid;
%let sexvar=sex;
%let racvar=race;
%let hisvar=hisp;
%let agevar=age;
%let prefix=b;
proc format;
value yesno
0 <- high = 'Y'
other = 'N';
value onezer
0 <- high = '1'
other = '0';
value frqb
11 - 20 = '11-20'
21-high = '21+';
value frqc
11 - 20 = '11-20'
21 - 30 = '21-30'
31 - 40 = '31-40'
41 - 50 = '41-50'
51-high = '51+';
value frqd
0 = '00'
1 - 2 = '01-02'
3 - 5 = '03-05'
6 - 10 = '06-10'
11 - 50 = '11-50'
51-high = '51+';
value frqe
7 - 10 = '07-10'
11-high = '11+';
run;
data hh_agg(drop=&sexvar &racvar &hisvar &agevar agedim1 agedim2 i j k l
s t);
set hh_rec;
by &key;
/********************* DEFINE AGGREGATION VARIABLE ARRAYS
******************/
array aggrvars{0:3,0:7,0:3,0:21} %cr8vlst;
array sextot {0:2} &prefix.sexm &prefix.sex1 &prefix.sex2;
array racnitot{0:6} &prefix.raceimp &prefix.race1ni &prefix.race2ni
&prefix.race3ni &prefix.race4ni &prefix.race5ni
&prefix.race6ni;
array ractot{0:6} &prefix.racem &prefix.race1 &prefix.race2
&prefix.race3
&prefix.race4 &prefix.race5 &prefix.race6;
array racflags{0:6} $ &prefix.racemfl &prefix.race1fl
&prefix.race2fl
&prefix.race3fl &prefix.race4fl
&prefix.race5fl
&prefix.race6fl;
array racindic{0:6} &prefix.racemfl2 &prefix.race1fl2
&prefix.race2fl2
&prefix.race3fl2 &prefix.race4fl2
&prefix.race5fl2
&prefix.race6fl2;
array hisnitot{0:2} &prefix.hispimp &prefix.hisp1ni &prefix.hisp2ni;
array histot{0:2} &prefix.hispm &prefix.hisp1 &prefix.hisp2;
array &prefix.artot{0:3} $ &prefix.arnum2-&prefix.arnum5;
/******************* INITIALIZE VARIABLES
*********************************/
if first.&key then do;
&prefix.arnum = 0;
do s=0 to 6;
racnitot{s} = 0;
ractot{s} = 0;
racflags{s} = ' ';
racindic{s} = 0;
if (0 <= s <= 3) then do;
&prefix.artot{s} = ' ';
if (0 <= s <= 2) then do;
sextot{s} = 0;
hisnitot{s} = 0;
histot{s} = 0;
end;
end;
end;
do i=0 to 3;
do j=0 to 7;
do k=0 to 3;
do l=0 to 21;
aggrvars{i,j,k,l} = 0;
end;
end;
end;
end;
end;
/*********************** START COUNTING
*********************************/
&prefix.arnum + 1;
if not (1 <= &sexvar <= 2) then &sexvar = 0;
if not (1 <= &racvar <= 6) then &racvar = 0;
if not (1 <= &hisvar <= 2) then &hisvar = 0;
select;
when ('000' le &agevar le '084') agedim1 =
int(input(&agevar,3.0)/5) + 1;
when ('085' le &agevar ) agedim1 = 18;
otherwise agedim1 = 0;
end;
aggrvars{&sexvar,&racvar,&hisvar,agedim1} + 1;
select;
when (1 <= agedim1 <= 3) agedim2 = 19;
when (&agevar le '017') agedim2 = 19;
when (5 <= agedim1 <= 13) agedim2 = 20;
when ('018' le &agevar le '019') agedim2 = 20;
when (14 <= agedim1 <= 18) agedim2 = 21;
end;
aggrvars{&sexvar,&racvar,&hisvar,agedim2} + 1;
/********************************** SUBTOTALS FOR EACH LEVEL
*****************/
aggrvars{3,&racvar,&hisvar,agedim1} + 1;
aggrvars{3,&racvar,&hisvar,agedim2} + 1;
aggrvars{3,7,&hisvar,agedim1} + 1;
aggrvars{3,7,&hisvar,agedim2} + 1;
aggrvars{3,&racvar,3,agedim1} + 1;
aggrvars{3,&racvar,3,agedim2} + 1;
aggrvars{3,7,3,agedim1} + 1;
aggrvars{3,7,3,agedim2} + 1;
aggrvars{&sexvar,7,&hisvar,agedim1} + 1;
aggrvars{&sexvar,7,&hisvar,agedim2} + 1;
aggrvars{&sexvar,7,3,agedim1} + 1;
aggrvars{&sexvar,7,3,agedim2} + 1;
aggrvars{&sexvar,&racvar,3,agedim1} + 1;
aggrvars{&sexvar,&racvar,3,agedim2} + 1;
if (upcase(racdecfl) not in ('C' 'P')) then racnitot{&racvar} + 1;
else
racnitot{0} + 1;
if (upcase(hisdecfl) ne 'P') then hisnitot{&hisvar} + 1; else
hisnitot{0} + 1;
sextot{&sexvar} + 1;
ractot{&racvar} + 1;
histot{&hisvar} + 1;
/******************** SET FLAGS AND INDICATORS
*****************************/
if last.&key then do;
&prefix.raceimpfl = put(&prefix.raceimp,yesno.);
&prefix.hispimpfl = put(&prefix.hispimp,yesno.);
do t=0 to 6;
racflags{t} = put(ractot{t},yesno.);
racindic{t} = input(put(ractot{t},onezer.),1.);
select;
when (t = 0) &prefix.artot{t} = put(&prefix.arnum,frqb.);
when (t = 1) &prefix.artot{t} = put(&prefix.arnum,frqc.);
when (t = 2) &prefix.artot{t} = put(&prefix.arnum,frqd.);
when (t = 3) &prefix.artot{t} = put(&prefix.arnum,frqe.);
otherwise;
end;
end;
if (&prefix.nru2 in ('3' '4')) then &prefix.ar_nrfu = 'Y'; else
&prefix.ar_nrfu = 'N';
if (&prefix.arnum = max(of &prefix.race1--&prefix.race5)) then
&prefix.samerace='Y'; else
if (1 < sum(of &prefix.race1fl2--&prefix.race5fl2)) then
&prefix.samerace='N'; else
&prefix.samerace='X';
if (&prefix.arnum = max(&prefix.hisp1,&prefix.hisp2)) then
&prefix.samehisp='Y'; else
if (0 < min(&prefix.hisp1,&prefix.hisp2)) then
&prefix.samehisp='N'; else
&prefix.samehisp='X';
if (0 < max(of &prefix.race2--&prefix.race4)) then
&prefix.nonwhite='Y'; else
if (&prefix.arnum = ractot{1}) then &prefix.nonwhite='N'; else
&prefix.nonwhite='X';
if (0 < histot{1}) then &prefix.hispfl='Y'; else
if (&prefix.arnum = histot{2}) then &prefix.hispfl='N'; else
&prefix.hispfl='X';
output;
end;
run;
[text/html]
|