program define mob /**************************************************************/ /* computes the Prais mobility index from period 1 to 2 and an*/ /* appropriate bootstrap confidence interval */ /* */ /* syntax: mob ... ... */ /* */ /* where is a (longitudinal) weight */ /* are state dummies indicating whether or*/ /* not an individual is in state m = 1..M */ /* in period t = 1,2 */ /* */ /* if no weights are needed, generate a variable with all */ /* values set to 1 and use it as the weight variable */ /* */ /* Note: the bootstrap is a random process and may lead to */ /* missing values when statistics are calculated from the re- */ /* sample; this problem vanishes with increasing sample size */ /* */ /* for details see Biewen (2002): Bootstrap inference for */ /* inequality, mobility and poverty measurement, Journal */ /* of Econometrics, Vol. 108, pp. 317 – 342 */ /* */ /* copyright Martin Biewen 2001 */ /**************************************************************/ version 6 /* parse syntax */ syntax varlist /* set number of bootstrap replications and confidence level */ tempname reps conf nobs scalar `reps' = 100 scalar `conf' = 0.95 scalar `nobs' = _N /* count number of states */ tempname nosts local i = 1 while "``i''" != "" { local i = `i' + 1 } scalar `nosts' = (`i' - 1 - 1)/2 if `nosts' != int(`nosts') { di in red "error: wrong number of variables" exit } /* check if data consistent */ tempvar check quietly gen `check' = 0 local i = 2 while `i' <= 1 + `nosts' { quietly replace `check' = `check' + ``i'' quietly sum ``i'' if r(min)<0 | r(max)>1 { di in red "error: state dummies must be either 0 or 1" exit } local i = `i' + 1 } quietly count if `check' != 1 if r(N) != 0 { di in red "error: state dummies don't sum up to 1" exit } quietly replace `check' = 0 local i = 1 + `nosts' + 1 while `i' <= 1 + 2 * `nosts' { quietly replace `check' = `check' + ``i'' quietly sum ``i'' if r(min)<0 | r(max)>1 { di in red "state dummies must be either 0 or 1" exit } local i = `i' + 1 } quietly count if `check' != 1 if r(N) != 0 { di in red "error: state dummies don't sum up to 1" exit } /* compute mobility estimate */ mob_ind `0' tempname m scalar `m' = r(m) /* preserve and initialize post */ preserve tempname postnam tempfile boot quietly postfile `postnam' bm using `boot', replace /* bootstrap loop */ local i = 1 while `i' <= `reps' { restore, preserve bsample mob_ind `0' post `postnam' sqrt(`nobs') * (r(m) - `m') local i = `i' + 1 } postclose `postnam' /* generate lower and upper confidence bounds */ use `boot', clear sort bm tempname lm um scalar `lm' = `m' - bm[`reps' - int((-(`conf'/2) + 0.5) * `reps')] / sqrt(`nobs') scalar `um' = `m' - bm[int((-(`conf'/2) + 0.5) * `reps')] / sqrt(`nobs') /* print out results */ di _newline "------------------------------------------------------------------" di "Prais mobility index, estimate and bootstrap confidence interval" di "------------------------------------------------------------------" di "Confidence level = " %3.2f `conf' ", " %5.0f `reps' " bootstrap replications di "------------------------------------------------------------------" di "Prais index = " in green %7.6f `m' in yellow ", confidence interval " in green "[" %7.6f `lm' " ; " %7.6f `um' "]" di "------------------------------------------------------------------" restore end program define mob_ind, rclass /* returns r(m) */ quietly { /* initialize index */ tempname m scalar `m' = 0 /* count number of states */ tempname nosts local i = 1 while "``i''" != "" { local i = `i' + 1 } scalar `nosts' = (`i' - 1 - 1)/2 /* calculate products */ tempvar w quietly gen `w' = `1' local i = 1 while `i' <= `nosts' { tempvar d1`i' d2`i' n`i' d`i' local j = `i' + 1 quietly gen `d1`i'' = ``j'' local j = `i' + `nosts' + 1 quietly gen `d2`i'' = ``j'' quietly gen `n`i'' = `w' * `d1`i'' * `d2`i'' quietly gen `d`i'' = `w' * `d1`i'' /* calculate moments */ tempname n d quietly sum `n`i'' scalar `n' = r(mean) quietly sum `d`i'' scalar `d' = r(mean) /* contribution to mobility index */ scalar `m' = `m' + `n'/`d' local i = `i' + 1 } /* finish calculation of index */ scalar `m' = (`nosts' - `m')/(`nosts' - 1) /* return result */ return scalar m = `m' } end