#delimit; * -------------------------------------------------------------- ; * * Computes difference in differences estimator; * * syntax 1: * * dind v, over(bv2 bv1) ** this puts them in columns / rows same as tab would * --> * bv1 = * 1 2 * bv2 = a mu_a1 mu_a2 da * b mu_b1 mu_b2 db * d1 d2 d-in-d * * (where mu_a1 if the mean of v if bv1 == 1 and bv2 == a) * * syntax 2: * * dind a1 a2 b1 b2 * --> * mu_a1 mu_a2 da * mu_b1 mu_b2 db * d1 d2 d-in-d * * last modified 2 Oct 2007 to put both syntaxes in one command; * * NEEDS: allow infixes and prefixes if the variables are conveniently named; * * -------------------------------------------------------------- ; program dind, rclass; version 9.2; syntax varlist(min=1 max=4), [OVER(varlist min=2 max=2) SVY]; local s_opt = ("`svy'" == "svy"); * CHECK that one syntax is properly specified; loc vcount: list sizeof varlist; loc ocount: list sizeof over; if (`vcount' == 1 & `ocount' == 2) loc syntax = 1; else if (`vcount' == 4 & `ocount' == 0) loc syntax = 2; else {; di "{err}must specify either one main variable and two over variables, or four main variables and no over variables: {...}"; error 198; }; * widths for columns etc.; loc colw = 10; loc cw = `colw' + 2; loc tcolw = 3 * `colw'; loc tcw = `tcolw' + 1; loc labw = 12; loc lw = `labw' + 2; * SYNTAX 1; if `syntax' == 1 {; gettoken bv2 rest: over; gettoken bv1: rest; * check over variables take only two values each; forval i = 1/2 {; qui vallist `bv`i''; local vlist`i' = r(vals); local n: list sizeof vlist`i'; if `n' != 2 {; di "{err}more than 2 groups found, only 2 allowed"; error 420; }; }; * get values, recode and make interaction; gettoken v_1 rest: vlist1; gettoken v_2: rest; gettoken v_a rest: vlist2; gettoken v_b: rest; tempvar nbv1 nbv2 cross; qui recode `bv1' (`v_1' = 0) (`v_2' = 1), gen(`nbv1'); qui recode `bv2' (`v_a' = 0) (`v_b' = 1), gen(`nbv2'); qui gen `cross' = `nbv1' * `nbv2'; * run regression; if `s_opt' qui svy: reg `varlist' `nbv1' `nbv2' `cross'; else qui reg `varlist' `nbv1' `nbv2' `cross'; qui test `cross'; loc p = r(p); loc df1 = r(df); loc df2 = r(df_r); loc f = r(F); * get values for cells; matrix b = e(b); loc mu_a1 = b[1,4]; * constant; loc mu_a2 = b[1,4] + b[1,1]; * constant + coefficient on bv1; loc mu_b1 = b[1,4] + b[1,2]; * constant + coefficient on bv2; loc mu_b2 = b[1,4] + b[1,1] + b[1,2] + b[1,3]; * constant + coefficient on bv1, bv2 and interaction; * and differences; local da = `mu_a2' - `mu_a1'; local db = `mu_b2' - `mu_b1'; local d1 = `mu_b1' - `mu_a1'; local d2 = `mu_b2' - `mu_a2'; local d = `d2' - `d1'; * TABLE; loc h1: lab (`bv1') `v_1' `colw'; loc h2: lab (`bv1') `v_2' `colw'; loc ha: lab (`bv2') `v_a' `colw'; loc hb: lab (`bv2') `v_b' `colw'; loc bv1 = abbrev("`bv1'", `tcw'); loc bv2 = abbrev("`bv2'", `labw'); di; di "{txt} {space `labw'} {center `tcolw': `bv1'} "; di "{txt} {ralign `labw':`bv2'} {c |} {ralign `colw':`h1'} {c |} {ralign `colw':`h2'} {c |} {ralign `colw':diff}"; di "{txt}{hline `lw'}{c +}{hline `cw'}{c +}{hline `cw'}{c +}{hline `cw'}"; di "{txt} {ralign `labw':`ha'} {c |} {res}"%`colw'.4f `mu_a1' " {txt}{c |}{res} " %`colw'.4f `mu_a2' " {txt}{c |}{res} " %`colw'.4f `da' ; di "{txt}{hline `lw'}{c +}{hline `cw'}{c +}{hline `cw'}{c +}{hline `cw'}"; di "{txt} {ralign `labw':`hb'} {c |} {res}"%`colw'.4f `mu_b1' " {txt}{c |}{res} " %`colw'.4f `mu_b2' " {txt}{c |}{res} " %`colw'.4f `db' ; di "{txt}{hline `lw'}{c +}{hline `cw'}{c +}{hline `cw'}{c +}{hline `cw'}"; di "{txt} {ralign `labw':diff} {c |} {res}"%`colw'.4f `d1' " {txt}{c |}{res} " %`colw'.4f `d2' " {txt}{c |}{res} " %`colw'.4f `d' ; di; di "{txt} F(" %2.0f `df1' "," %6.0f `df2' ") = {res}" %5.2f `f' "{txt} p = {res}" %5.4f `p'; }; * SYNTAX 2; if `syntax' == 2 {; * get variables; gettoken a1 rest: varlist; gettoken a2 rest: rest; gettoken b1 rest: rest; gettoken b2: rest; * get means for cells and test diff-in-diff; if `s_opt' {; qui svy: mean `varlist'; matrix mm = e(b); matrix nn = e(_N); loc i = 1; foreach x in a1 a2 b1 b2 {; local mu_`x' = mm[1, `i']; loc i = `i'+1; }; qui test ([`b2'] - [`b1']) - ([`a2'] - [`a1']) = 0; loc p = r(p); loc t = r(t); }; else {; tempvar dvar; qui gen `dvar' = (`b2' - `b1') - (`a2' - `a1'); foreach x in a1 a2 b1 b2 {; qui sum ``x'' if `dvar' < .; local mu_`x' = r(mean); }; qui ttest `dvar' == 0; loc p = r(p); loc t = r(t); }; * calculate differences; local da = `mu_a2' - `mu_a1'; local db = `mu_b2' - `mu_b1'; local d1 = `mu_b1' - `mu_a1'; local d2 = `mu_b2' - `mu_a2'; local d = `d2' - `d1'; * TABLE; loc a1 = abbrev("`a1'", 16); loc a2 = abbrev("`a2'", 16); loc b1 = abbrev("`b1'", 16); loc b2 = abbrev("`b2'", 16); di; di "{txt}{ralign 20: (`a1')} {c |} {ralign 20: (`a2')}{c |} "; di "{res}"%20.4f `mu_a1' " {txt}{c |}{res}" %20.4f `mu_a2' " {txt}{c |}{res}" %10.4f `da' ; di "{txt}{hline 21}{c +}{hline 21}{c +}{hline 11}"; di "{txt}{ralign 20: (`b1')} {c |} {ralign 20: (`b2')}{c |}"; di "{res}"%20.4f `mu_b1' " {txt}{c |}{res}" %20.4f `mu_b2' " {txt}{c |}{res}" %10.4f `db'; di "{txt}{hline 21}{c +}{hline 21}{c +}{hline 11}"; di "{res}"%20.4f `d1' " {txt}{c |}{res}" %20.4f `d2' " {txt}{c |}{res}" %10.4f `d'; di; di "{txt} t = {res}" %3.2f `t' "{txt} p-value = {res}" %5.4f `p'; }; * RETURN VALUES; return scalar p = `p'; return scalar mu_a1 = `mu_a1'; return scalar mu_a2 = `mu_a2'; return scalar mu_b1 = `mu_b1'; return scalar mu_b2 = `mu_b2'; end;