*!version 1.0 Helmut Farbmacher (January 2014) // Postestimation command for ivreg2 prog nwind, eclass version 10 if "`e(cmd)'"!="ivreg2" { dis as error "You have to call 'ivreg2' first." exit 198 } if "`e(model)'"!="cue" | "`e(vcetype)'"!="Robust" { dis as error "You have to use the options 'cue' and 'robust' in the ivreg2 command." exit 198 } if "`e(cons)'"=="0" { nwind_calc `e(depvar)' `e(instd)' `e(inexog)', endog(`e(instd)') exog(`e(insts)') cluster(`e(clustvar)') noconstant } else { nwind_calc `e(depvar)' `e(instd)' `e(inexog)', endog(`e(instd)') exog(`e(insts)') cluster(`e(clustvar)') } end prog nwind_calc, eclass syntax varlist [if] [in], [endog(varlist) exog(varlist) cluster(varname) NOCONstant] marksample touse markout `touse' `exog' `endog' gettoken lhs varlist : varlist loc rhs: list varlist | endog loc exog_xs: list varlist & exog loc z: list varlist | exog loc z: list z-endog loc ivs: list exog - exog_xs loc endog_x: list rhs - exog_xs if "`noconstant'"!="" { mat b=J(1,`:word count `rhs'',0) mat V=J(`:word count `rhs'',`:word count `rhs'',0) matname b `rhs',c(.) matname V `rhs',c(.) matname V `rhs',r(.) } else { mat b=J(1,`:word count `rhs' _cons',0) mat V=J(`:word count `rhs' _cons',`:word count `rhs' _cons',0) matname b `rhs' _cons,c(.) matname V `rhs' _cons,c(.) matname V `rhs' _cons,r(.) } //nocons mat nocons123=0 if "`noconstant'"!="" { mat nocons123=1 } mat beta123=e(b) dis "" dis as text "Newey and Windmeijer's (2009) standard errors:" if "`cluster'"=="" { tempvar cluster gen `cluster'=_n local nocluster="1" } mat numi=J(1,1,.) tempvar touse gen `touse'=e(sample) mata: ivp2_nwind("`cluster'","`lhs'","`rhs'","`z'","`touse'") //output eret post b V, e(`touse') depname(`lhs') eret di if "`nocluster'"=="" { dis "Number of clusters = {res}" numi[1,1] } end *** Mata *** ************ mata: //calculate Newey and Windmeijer's (2009) SE void ivp2_nwind(string scalar idvar,string scalar lhs,string scalar rhs,string scalar z, string scalar ok) { external y,X,Z,W // id & panel setup st_view(id,.,idvar,ok) panel = panelsetup(id,1) panelst = panelstats(panel) numi = panelst[1] st_replacematrix("numi",numi) y=st_data(.,tokens(lhs),ok) nocons=st_matrix("nocons123") if (nocons==1) { X=st_data(.,tokens(rhs),ok) Z=st_data(.,tokens(z),ok) } if (nocons==0) { cons=J(rows(y),1,1) X=st_data(.,tokens(rhs),ok),cons Z=st_data(.,tokens(z),ok),cons } p=st_matrix("beta123") par=cols(X) mend=J(cols(Z),1,0) Wend=J(cols(Z),cols(Z),0) eps=y :- X*p' m=quadcross(Z,eps)/rows(panel) Zu_N=J(rows(panel),cols(Z),.) for(i=1; i<=numi; i++) { epsi = eps[|panel[i,1],1 \ panel[i,2],1|] Zi = Z[|panel[i,1],1 \ panel[i,2],cols(Z)|] Zu_N[i,.]=quadcross(Zi,epsi)' } Wend = quadcross(Zu_N,Zu_N) W = luinv((1/rows(panel))*Wend) //Hessian G=quadcross(Z,-X) H=quadcross(G,W)*G/rows(panel) for (j=1; j<=par; j++) { lambdaj=J(cols(Z),cols(Z),0) for(i=1; i<=numi; i++) { epsi = eps[|panel[i,1],1 \ panel[i,2],1|] Xj = -X[|panel[i,1],j \ panel[i,2],j|] Zi = Z[|panel[i,1],1 \ panel[i,2],cols(Z)|] lambdaj = lambdaj + quadcross(quadcross(quadcross(Zi,Xj)',epsi')',Zi)/rows(panel) } for (k=1; k<=par; k++) { H[j,k] = H[j,k] - G[.,k]'*W*(lambdaj+lambdaj')*W*m } for (i=1; i<=numi; i++) { epsi = eps[|panel[i,1],1 \ panel[i,2],1|] Xi = X[|panel[i,1],1 \ panel[i,2],cols(X)|] Zi = Z[|panel[i,1],1 \ panel[i,2],cols(Z)|] for (k=1; k<=par; k++) { lambdak = -quadcross(quadcross(quadcross(Zi,Xi[.,k])',epsi')',Zi)/rows(panel) dellambda_jk=quadcross(quadcross(quadcross(Zi,Xi[.,j])',Xi[.,k]')',Zi)/rows(panel) H[j,k] = H[j,k] - G[.,j]'*W*(lambdak+lambdak')*W*m + rows(panel)*m'*W*(lambdak+lambdak')*W*(lambdaj+lambdaj')*W*m - rows(panel)*m'*W*dellambda_jk*W*m } } } Hes=H/rows(panel) S=J(cols(Z),par,.) for (j=1; j<=par; j++) { //fill S s1=(1/rows(panel))*quadcross(Z,((-X[.,j]))) lambdaj=J(cols(Z),cols(Z),0) for(i=1; i<=numi; i++) { epsi = eps[|panel[i,1],1 \ panel[i,2],1|] Xj = -X[|panel[i,1],j \ panel[i,2],j|] Zi = Z[|panel[i,1],1 \ panel[i,2],cols(Z)|] lambdaj = lambdaj + quadcross(quadcross(quadcross(Zi,Xj)',epsi')',Zi)/rows(panel) } s2=quadcross(quadcross(lambdaj',W)',m) s=s1-s2 S[.,j]=s } middle=quadcross(quadcross(S,W)',S) vce=(1/rows(panel))*(quadcross(quadcross(luinv(Hes)',middle)',luinv(Hes))) _makesymmetric(vce) st_replacematrix("b",p) st_replacematrix("V",vce) } end