* code to generate tables 1-6 in Roodman & Morduch, JDS. Results tabulated in a text file produced via outreg2, which is imported into Excel for formatting global resultsfile pk982.txt global meansfile PK 98 means 2.txt cap log close log using "PK 98 reproduction", replace cap estimates drop * cap erase $resultsfile set more off set matsize 800 cmp setup global indy $cmp_cont scalar C_t = ln(1000) scalar C_v = ln(1) do "PK reproduction 2 routines.do" PrepHHData tempfile TempOutregFile // on my computer, saving to CGD file server makes outreg2 crash * Table 1: weighted means and sds of RHS vars in first wave. sd's are displayed as "Root MSE" foreach var in fbraclvpk mbraclvpk fbrdblvpk mbrdblvpk fgramlvpk mgramlvpk scoheadpk afedhighpk amedhighpk afadultdpk amadultdpk sexheadpk ageheadpk landbefpk edheadpk spsislnddpk spbrolnddpk spparlnddpk hdsislnddpk hdbrolnddpk hdparlnddpk nontarpk { cap reg `var' if wave==1 [aw=weightpk] if !_rc { reg qui outreg2 using "`TempOutregFile'", noparen noaster ctitle("`var'-wave 1") dec(10) adec(10) addstat("S.d.", `=string(e(rmse), "%12.4f")') } } * Table 2: means and sds of dep vars. sd's are displayed as "Root MSE". forvalues varn = 1/9 { if `varn'==6 { preserve * odbc load, exec("select * from [Roodman & Morduch ind]") dsn(PK) clear use "Roodman & Morduch ind 2.dta", clear keep if wave<4 & pksample ren pksamplempk choicempk ren pksamplefpk choicefpk bysort villagepk: egen byte fprogvillpk = max(choicefpk) by villagepk: egen byte mprogvillpk = max(choicempk) gen byte progvillpk = fprogvillpk | mprogvillpk reg age if wave==1 [aw=weightpk] qui outreg2 using "`TempOutregFile'", noparen noaster ctitle("age-wave 1") dec(10) adec(10) addstat("S.d.", `=string(e(rmse), "%12.4f")') reg ed if wave==1 & age>=5 [aw=weightpk] qui outreg2 using "`TempOutregFile'", noparen noaster ctitle("ed-wave 1") dec(10) adec(10) addstat("S.d.", `=string(e(rmse), "%12.4f")') reg edns if wave==1 & age>=5 [aw=weightpk] // education of non-students, students=0, needed to match PK qui outreg2 using "`TempOutregFile'", noparen noaster ctitle("edns-wave 1") dec(10) adec(10) addstat("S.d.", `=string(e(rmse), "%12.4f")') } local var : word `varn' of fproglvpk mproglvpk pcnsexppk fasset fnlasset fwork mwork fedec517 medec517 local varsample : word `varn' of "choicefpk & wave==1" "choicempk & wave==1" /// 1 "!afadultdpk & wave==1" "!afadultdpk & wave==1" /// "sex==0 & age>=16 & age<60" "sex==1 & age>=16 & age<60" /// "wave==1 & sex==0 & age>=5 & age<18" "wave==1 & sex==1 & age>=5 & age<18" * more proper but doesn't match original: * local varsample : word `varn' of "choicefpk & !afadult & wave==1" "choicempk & !amadult & wave==1" /// * 1 "!afadultdpk & wave==1" "!afadultdpk & wave==1" "sex==0 & age>=16 & age<60" /// * "sex==1 & age>=16 & age<60" "wave==1 & sex==0" /// * "wave==1 & sex==0 & age>=5 & age<18" "wave==1 & sex==1 & age>=5 & age<18" forvalues samplen = 1/5 { local sample : word `samplen' of progid<4 "progid>=4 & progvillpk" progvillpk !progvillpk 1 local samplename : word `samplen' of part non-part prog-vill non-prog-vill all cap reg `var' if `varsample' & `sample' [aw=weightpk] if !_rc { reg qui outreg2 using "`TempOutregFile'", noparen noaster ctitle("`var'-`samplename'") dec(10) adec(10) addstat("S.d.", `=string(e(rmse), "%12.4f")') } } } restore copy "`TempOutregFile'" "$meansfile", replace tempfile TempOutregFile global TempOutregFile `TempOutregFile' *** Regressions reported in response to Pitt (2011) global covsf scoheadpk afedhighpk amedhighpk amadultdpk sexheadpk ageheadpk llandbefpk edheadpk spsislnddpk spbrolnddpk spparlnddpk hdsislnddpk hdbrolnddpk hdparlnddpk _Iwave* i.villagepk#i.choicefpk global covsm scoheadpk afedhighpk amedhighpk afadultdpk sexheadpk ageheadpk llandbefpk edheadpk spsislnddpk spbrolnddpk spparlnddpk hdsislnddpk hdbrolnddpk hdparlnddpk _Iwave* i.villagepk#i.choicempk global creditvars lfbraclvpk lfbrdblvpk lfgramlvpk lmbraclvpk lmbrdblvpk lmgramlvpk global creditw lfproglvpk global creditm lmproglvpk global extracovsy crcensored global nontarvar DefineIndicators * a la RM 2009--use crcensored instead of nontar, censor credit vars in 2nd stage with log 1000 instead of log 1, vary all vars over time preserve recode $creditvars (0 = `=ln(1000)') EstimatePK SaveEstimates, runname(RM2009) * now drop crcensored, like PK global extracovsy EstimatePK SaveEstimates, runname(RM2009_nocrcensored) * in addition, now censor with log 1, like PK restore // ...credit var censoring back at log 1 EstimatePK SaveEstimates, runname(RM2009_nocrcensored_ln1) * instead of fixing censoring issue by censoring with log 1, fix missing nontar global nontarvar nontarpk preserve recode $creditvars (0 = `=ln(1000)') EstimatePK SaveEstimates, runname(RM2009_nocrcensored_nontar) restore // ...credit var censoring back at log 1 * Now do both important fixes--censoring with ln1 and include nontar, like PK EstimatePK SaveEstimates, runname(allrounds) * REPLICATION: reported in response to Pitt (2011) and in Roodman & Morduch, JDS: give 1st-stage & credit vars wave-1 values throughout; include nontar; drop crcensored; censor with log 1 ResetGlobals DefineIndicators EstimatePKFlip, runname(replication) // Roodman & Morduch Table 3, col 2; Table 4, cols 1-2 * Linear LIML EstimateLIML SaveEstimates, runname(LIML) // Table 5, col 1 global creditvars lfproglvpk1ln1 lmproglvpk1ln1 EstimateLIML // Table 5, col 2 SaveEstimates, runname(LIML2var) EstimateLIML if fprogvillpk & mprogvillpk // not in paper: restrict to villages where both genders can borrow SaveEstimates, runname(LIML_both_only) global insts choicefpk1 choicempk1 EstimateLIML // Table 5, col 3 SaveEstimates, runname(LIMLExactID) * not in paper: pool credit across gender, linear LIML global creditvars lproglvpk1ln1 global insts zb* choicepk1 EstimateLIML SaveEstimates, runname(LIMLPooled) * not in paper: pool credit across gender, linear, instrument only with choice dummy global insts choicepk1 EstimateLIML SaveEstimates, runname(LIMLPooledExactID) ResetGlobals * vary sample by gender global creditvars lfbraclvpk1 lfbrdblvpk1 lfgramlvpk1 EstimatePKFlip if !mprogvillpk, femaleonly runname(femaleonly) // Table 4, col 4 global creditvars lmbrdblvpk1 lmgramlvpk1 EstimatePKFlip if !fprogvillpk, maleonly runname(maleonly) // Table 4, col 5 ResetGlobals EstimatePKFlip if !(fprogvillpk & mprogvillpk), runname(single_gender) // Table 4, col 7 EstimatePKFlip if fprogvillpk & mprogvillpk, runname(bothonly) // Table 4, col 6 * ... instead, dichotomize credit preserve Probitize EstimatePKFlip, runname(probit) // Table 3, col 3 replace indf = $cmp_cont replace indm = $cmp_cont EstimatePKFlip, runname(LPM) // treat binary borrowing variables with linear probability model (used only in http://www.cgdev.org/blog/somewhat-less-provisional-analysis-pitt-khandker) restore ResetGlobals * ... instead, expand first-stage equations to full sample (used only in http://www.cgdev.org/blog/somewhat-less-provisional-analysis-pitt-khandker) preserve replace choicefpk = 1 replace choicempk = 1 EstimatePKFlip, runname(full_sample) restore * ...instead add instruments (choice interaction terms) to second stage global extracovsy choicefpk choicempk EstimatePKFlip, runname(choice_in_stage_2) // Table 3, col 5 global extracovsy zf* zm* choicefpk choicempk EstimatePKFlip, runname(z_in_stage_2) // Table 3, col 6 ResetGlobals * ...instead switch to de jure eligibility global nontarvar nontrgth_dejure gen byte choicefDejure = !$nontarvar * fprogvillpk gen byte choicemDejure = !$nontarvar * mprogvillpk gen byte choiceDejure = !$nontarvar * progvillpk foreach var of varlist $covsf { cap drop zf`var' gen double zf`var' = `var' * choicefDejure } foreach var of varlist $covsm { cap drop zm`var' gen double zm`var' = `var' * choicemDejure } global insts zf* zm* choicefDejure choicemDejure global creditvars lfproglvpk1ln1 lmproglvpk1ln1 EstimateLIML SaveEstimates, runname(LIMLDejure) // Table 5, col 4 preserve Probitize EstimateLIML SaveEstimates, runname(LIMLDejure2varDichot) // Table 5, col 6 restore global insts choicefDejure choicemDejure EstimateLIML SaveEstimates, runname(LIMLDejureExactID) // Table 5, col 5 preserve Probitize EstimateLIML SaveEstimates, runname(LIMLDejure2varDichotExactID) // Table 5, col 7 restore global creditvars lproglvpk1ln1 global insts zb* choiceDejure EstimateLIML SaveEstimates, runname(LIMLPooledDejure) // not in paper: pool across gender, all instruments global insts choiceDejure EstimateLIML SaveEstimates, runname(LIMLPooledDejureExactID) // not in paper: pool across gender, instrument with de jure credit choice dummies only global creditvars lfbraclvpk1 lfbrdblvpk1 lfgramlvpk1 lmbraclvpk1 lmbrdblvpk1 lmgramlvpk1 global covsf zf* choicefDejure, nocons global covsm zm* choicemDejure, nocons global covsfm zf* zm* choice?Dejure, nocons replace choicefpk = fprogvillpk // instrument all HH in program villages--seems only way to define treatment-control exogenously replace choicempk = mprogvillpk // while embracing all HH that borrowed, including mistargeted ones EstimatePKFlip, runname(dejure) tech(dfp) // Table 3, col 4 global extracovsy choicefDejure choicemDejure EstimatePKFlip, runname(dejureChoiceStage2) tech(dfp) // Table 3, col 7 global extracovsy zf* zm* choicefDejure choicemDejure EstimatePKFlip, runname(dejureZstage2) tech(dfp) // Table 3, col 8 ResetGlobals * vary sample by gender, de jure (not in paper) global creditvars lfbraclvpk1 lfbrdblvpk1 lfgramlvpk1 EstimatePKFlip if !mprogvillpk, femaleonly runname(femaleonlyDejure) global creditvars lmbrdblvpk1 lmgramlvpk1 EstimatePKFlip if !fprogvillpk, maleonly runname(maleonlyDejure) ResetGlobals EstimatePKFlip if !(fprogvillpk & mprogvillpk), runname(single_genderDejure) EstimatePKFlip if fprogvillpk & mprogvillpk, runname(bothonlyDejure) global creditvars lbraclvpk1 lbrdblvpk1 lgramlvpk1 EstimatePKFlip, runname(aggGenderDejure) pooled difficult PrepHHData DefineIndicators * aggregate 2nd-stage credit vars accross gender global creditvars lbraclvpk1 lbrdblvpk1 lgramlvpk1 EstimatePKFlip, runname(aggGender) pooled // Table 4, col 3 ResetGlobals * Method suggested in text: Model and instrument binary and continuous aspects of credit separately * Doesn't seem to coverge, probably because of poor instruments for borrowing amount /*bysort nh: gen byte fproglvpk1d = fproglvpk[1]>0 bysort nh: gen byte mproglvpk1d = mproglvpk[1]>0 replace fproglvpk1 = fproglvpk1 * fproglvpk1d replace mproglvpk1 = mproglvpk1 * mproglvpk1d cmp (lpcnsexppk = fproglvpk1d fproglvpk1 mproglvpk1d mproglvpk1 $nontarvar $covsy _Ivill*) (fproglvpk1d = $covsf) (fproglvpk1 = $covsf) /// (mproglvpk1d = $covsm) (mproglvpk1 = $covsm) [pw=weightpk], tech(dfp nr) cluster(nh) /// ind($cmp_cont choicefpk*$cmp_probit choicefpk*fproglvpk1d choicempk*$cmp_probit choicempk*mproglvpk1d) cmp (lpcnsexppk = fproglvpk1d fproglvpk1 mproglvpk1d mproglvpk1 $nontarvar $covsy _Ivill*) (fproglvpk1d = $covsf) (fproglvpk1 = $covsf) /// (mproglvpk1d = $covsm) (mproglvpk1 = $covsm) [pw=weightpk] if !((fproglvpk1d & !choicefpk) | (mproglvpk1d & !choicempk)), tech(dfp nr) cluster(nh) /// ind($cmp_cont choicefpk*$cmp_probit choicefpk*fproglvpk1d choicempk*$cmp_probit choicempk*mproglvpk1d) pseudod2 cmp (lpcnsexppk = fproglvpk1d fproglvpk1 mproglvpk1d mproglvpk1 $nontarvar $covsy _Ivill*) (fproglvpk1d = $covsf) (fproglvpk1 = $covsf) /// (mproglvpk1d = $covsm) (mproglvpk1 = $covsm) [pw=weightpk], tech(dfp nr) cluster(nh) /// ind($cmp_cont choicefpk*$cmp_probit choicefpk*$cmp_cont choicempk*$cmp_probit choicempk*$cmp_cont) */ * outcome: log female (non-land) assets scalar Y_0 = ln(10) // female non-land asset censoring threshold? (2 is lowest observed value, in wave 2, 10 lowest in wave 1.) gen double lfnlasset = ln(fnlasset) gen double lfasset = ln(fasset) replace lfnlasset = Y_0 if lfnlasset=16 & age<60 & sex==0, runname($depvar) // Table 6, col 5 global depvar lmwork global indy cond($depvar<=Y_0, $cmp_left, $cmp_cont) gen byte d = mwork==0 sum d [aw=weightpk] if !afadultdpk & age>=16 & age<60 & sex==1, mean di "share of male labor supply obs that are censored:" r(mean) EstimatePKFlip if !amadultdpk & age>=16 & age<60 & sex==1, runname($depvar) // Table 6, cols 7-8 * outcome: school enrollment global extracovsy age age2 global indy $cmp_probit global depvar fedec517 EstimatePKFlip if wave==1 & sex==0 & age>=5 & age<18, runname($depvar) tech(dfp) // Table 6, cols 10 global depvar medec517 EstimatePKFlip if wave==1 & sex==1 & age>=5 & age<18, runname($depvar) // Table 6, cols 12 * outcome: contraception, as in Pitt, Khandker, McKernan, and Latif 1999 (not in paper) global extracovsy age age2 global indy $cmp_probit global depvar contracep_1450 EstimatePKFlip if wave==1 & sex==0 & age>=14 & age<=50 & mar==2, runname($depvar) femaleonly global depvar contracep_1430 EstimatePKFlip if wave==1 & sex==0 & age>=14 & age<=30 & mar==2, runname($depvar) femaleonly * outcome: fertility, as in Pitt, Khandker, McKernan, and Latif 1999 (not in paper) global extracovsy age age2 global indy $cmp_probit global depvar childpost88_1450 EstimatePKFlip if wave==1 & sex==0 & age>=14 & age<=50 & mar==2, runname($depvar) femaleonly global depvar childpost88_1430 EstimatePKFlip if wave==1 & sex==0 & age>=14 & age<=30 & mar==2, runname($depvar) femaleonly copy "$TempOutregFile" "$resultsfile", replace log close