/*****************************************************************************/

/*****************************************************************************/

*SAS Code SP Weights.sas

*Author: Abt SRBI

*Created: 6/25/12

Purpose: This is SAS code that creates weights for respondents to the Inland

and National versions of the 316(b) stated preference (SP) survey.

/*****************************************************************************/

/*****************************************************************************/

/* Assign a library to access dataset with imputed raking variables*/

libname impute ''; options nofmterr; run;

/*******************************************************************************/

/*** NATIONAL WEIGHTS

***/

/*******************************************************************************/

data national; set data1;

/*filter on national respondents*/

where region=5;

** Recode gender;

gender=0;

if q13=1 then gender=1;

if q13=2 then gender=2;

if q13=. then gender=99;

** Recode income;

income=2;

if q23 le 4 then income=1;

if q23=. then income=99;

** Recode age;

*use modal response to impute 10 missing cases in age to use to impute

gender;

age_i=0;

if q12 ge 18 and q12 le 34 then age_i=1;

if q12 ge 35 and q12 le 64 then age_i=2;

if q12 ge 65 then age_i=3;

if q12=. then age_i=2; /*impute 10 missing cases as modal response to

help impute gender*/

** Recode household size;

*imputed modal response of Q15 (household size) to use as starting point

in imputation of age and gender;

q15_i=q15;

if q15 ge 5 then q15_i=5;

if q15=. then q15_i=2; /*for 14 cases missing data, impute as 2 person

HH*/

*create a dummy baseweight for raking with all values set equal to 1;

basewt=1;

*add variable labels;

label q23="household income";

label q22_5="race: white or not";

label q14="education level";

label q12="age";

label q13="gender";

label income="income $59,999 or less";

proc format;

value agef 1='18-34' 2='35-64' 3='65+';

value regionf 1='northeast' 2='southeast' 3='inland' 4='pacific'

5='national';

value race 1='white' 2='other';

value gender 1='male' 2='female';

value educ 1='less than bachelor''s degree' 2='bachelor''s degree or

higher';

value income 1='$59,999 or less' 2='More than $59,999';

run;

proc datasets lib=work;

modify national;

format age_i age agef.;

format region regionf.;

Page 1
format gender gender.;

format educ educ.;

format income income.;

format white race.;

run;

/*check recodes;

proc freq data=national; tables region q15_i*q15 age_i gender gender*q13 income

income*q23 basewt Q15_i q15 q16 q17 gender/ list missing;

run; */

** National sample has 10 cases missing gender and 30 cases missing income ;

** Merge imputed raking variables into national dataset;

PROC SORT data=impute.national_imputed; BY id; RUN;

PROC SORT data=national; BY id; RUN;

DATA national2; MERGE national (in=a) impute.national_imputed; BY id; if

a; RUN;

** Check the merged dataset;

PROC CONTENTS data=national2 varnum; RUN;

PROC FREQ data=national2; TABLES gender*gender_i income*income_i basewt/

LIST MISSING; RUN;

/* The raking invokes an external macro developed by David Izrael, David C.

Hoaglin, and Michael P. Battaglia at Abt Associates.

More information on this macro can be found here:

http://abtassociates.com/AbtAssociates/files/e1/e13f32cf-6957-4b0b-bde4-327b18cd3

f05.pdf */

%include '';

DATA gender_i; INPUT gender_i PERCENT; DATALINES;

1 0.485

2 0.515

;

RUN;

DATA income_i; INPUT income_i PERCENT; DATALINES;

1 0.565

2 0.435

;

RUN;

%rakinge (inds=national2, /* input

data set */

outds=national2_raked, /* output

data set */

inwt=basewt,

/* weight to be raked */

freqlist=gender_i income_i,

/* list of data sets with marginal control totals. They must

contain

the name of raking variable and either variable PERCENT

or MRGTOTAL

(e.g. direct counts of marginal control totals) by

default it is assigned

names of raking variables */

outwt=NATIONAL_WGT,

/* resulting raked weight */

/* byvar= varTK, */

/* variable BY which user might want to set up raking. By default, raking

is done over the whole input data set. (If you use this

then you need

to adjust marginal control files */

varlist=gender_i income_i,

/* list of variables to be raked on */

numvar=2,

/* number of raking variables */

Page 2
cntotal=28800,

/* Enter N x 100 for datasets set N equal to license frame size*/

trmprec=1,

/* tolerance,default is 1 (increase if raking time is too long)*/

numiter=20,

/* number of iterations,default is 50*/

prdiag =Y);

/* print detailed diagnostics */

** Check that weights sum to the uniweighted sample size;

PROC UNIVARIATE data=national2_raked; VAR NATIONAL_WGT; RUN;

/*******************************************************************************/

/*** INLAND WEIGHTS

***/

/*******************************************************************************/

data inland; set data1;

/*filter on inland respondents*/

where region=3;

* Recode Age;

age=0;

if q12 ge 18 and q12 le 34 then age=1;

if q12 ge 35 and q12 le 64 then age=2;

if q12 ge 65 then age=3;

if q12=. then age=99;

if q12 < 18 then age=99;

* Recode gender;

gender=0;

if q13=1 then gender=1;

if q13=2 then gender=2;

if q13=. then gender=99;

* Recode race;

white=2;

if q22_5=1 or q22_5=5 then white=1; /*according to email from Kim*/

if q22_5=. then white=99;

* Recode education;

educ=1;

if q14 in (5,6) then educ=2;

if q14=. then educ=99;

* Recode income;

income=2;

if q23 le 4 then income=1; /*income $59,999 or less*/

if q23=. then income=99;

* Recode household size;

*imputed modal response of Q15 (household size) to use as starting point

in imputation of age and gender;

if q15=. then q15=2;

*create a dummy baseweight for raking with all values set equal to 1;

basewt=1;

*add variable labels;

label q23="household income";

label q22_5="race: white or not";

label q14="education level";

label q12="age";

label q13="gender";

label income="income $59,999 or less";

proc format;

value agef 1='18-34' 2='35-64' 3='65+';

value regionf 1='northeast' 2='southeast' 3='inland' 4='pacific'

5='national';

value race 1='white' 2='other';

value gender 1='male' 2='female';

value educ 1='less than bachelor''s degree' 2='bachelor''s degree or

higher';

value income 1='$59,999 or less' 2='More than $59,999';

run;

proc datasets lib=work;

modify inland;

format age agef.;

Page 3
format region regionf.;

format gender gender.;

format educ educ.;

format income income.;

format white race.;

run;

/* check recodes

proc freq data=inland; tables white white*q22_5 gender gender*q13 educ educ*q14

income income*q23 region age*q12 basewt q15 q16 q17 age gender/ list missing;

run; */

** Inland sample has 13 cases missing gender, 43 cases missing race, 19 cases

missing education level, 68 cases missing income, and 20 cases missing age;

** Merge imputed raking variables into inland dataset;

PROC SORT data=impute.inland_imputed; BY id; RUN;

PROC SORT data=inland; BY id; RUN;

DATA inland2; MERGE inland (in=a) impute.inland_imputed; BY id;

if a;RUN;

** Check the merged dataset;

PROC CONTENTS data=inland2 varnum; RUN;

PROC FREQ data=inland2; TABLES age_i gender_i educ_i white_i income_i

/list missing; RUN;

/* The raking invokes an external macro developed by David Izrael, David C.

Hoaglin, and Michael P. Battaglia at Abt Associates.

More information on this macro can be found here:

http://abtassociates.com/AbtAssociates/files/e1/e13f32cf-6957-4b0b-bde4-327b18cd3

f05.pdf */

%include '';

DATA gender_i; INPUT gender_i PERCENT; DATALINES;

1 0.488

2 0.512

;

RUN;

DATA educ_i; INPUT educ_i PERCENT; DATALINES;

1 0.765

2 0.235

;

DATA white_i; INPUT white_i PERCENT; DATALINES;

1 0.826

2 0.174

;

DATA income_i; INPUT income_i PERCENT; DATALINES;

1 0.595

2 0.405

;

DATA age_i; INPUT age_i PERCENT; DATALINES;

1 0.301780

2 0.522285

3 0.175935

;

RUN;

%rakinge (inds=inland2, /* input

data set */

outds=inland2_raked, /* output

data set */

inwt=basewt,

/* weight to be raked */

freqlist=gender_i educ_i white_i income_i age_i,

/* list of data sets with marginal control totals. They must

contain

the name of raking variable and either variable PERCENT

or MRGTOTAL

(e.g. direct counts of marginal control totals) by

Page 4
default it is assigned

names of raking variables */

outwt=INLAND_WGT,

/* resulting raked weight */

/* byvar= varTK, */

/* variable BY which user might want to set up raking. By default, raking

is done over the whole input data set. (If you use this

then you need

to adjust marginal control files */

varlist=gender_i educ_i white_i income_i age_i,

/* list of variables to be raked on */

numvar=5,

/* number of raking variables */

cntotal=78700,

/* Enter N x 100 for datasets set N equal to license frame size*/

trmprec=1,

/* tolerance,default is 1 (increase if raking time is too long)*/

numiter=20,

/* number of iterations,default is 50*/

prdiag =Y);

/* print detailed diagnostics */

** Check unweighted and weighted estimates;

PROC FREQ data=inland2_raked; TABLES gender_i educ_i white_i income_i

age_i; RUN;

PROC FREQ data=inland2_raked; WEIGHT INLAND_WGT; TABLES gender_i educ_i

white_i income_i age_i; RUN;

** Check that weights sum to the license frame size;

PROC UNIVARIATE data=inland2_raked; VAR INLAND_WGT; RUN;

** Trim weights;

data inland2_raked_trimmed; set inland2_raked;

if INLAND_WGT > 6.61843659169781 then INLAND_WGT=6.61843659169781;

INLAND_WGT = INLAND_WGT + ((787-781.435242)/787);

RUN;

PROC UNIVARIATE data=inland2_raked_trimmed; VAR INLAND_WGT; RUN;

Page 5