LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (May 2002, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments: To: mark.k.moran@CENSUS.GOV
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]


Back to: Top of message | Previous page | Main SAS-L page