capture program drop twres capture mata mata drop projVar() capture mata mata drop microMataLoad() findfile twset.ado include "`r(fn)'" mata void microMataLoad() { string scalar newid,newt, w, root root =st_local("using") w = readMat(root,"twoWayW") var1= readMat(root,"twoWayVar1") var2= readMat(root,"twoWayVar2") st_local("var1",var1) st_local("var2",var2) st_local("w",w) } end mata void projVar() { real matrix V, varIn, D,aux,delta,tau,varOut,A,B,CinvHHDH,AinvDDDH,C real colvector invHH,invDD,Dy,Ty real scalar N,T, correction_rank, save_to_e string scalar newid, newt, currvar,newvar,sampleVarName,w,linear_index,var1,var2, root root=st_local("using") save_to_e=st_numscalar("save_to_e") currvar = st_local("currvar") newvar = st_local("newvar") var1 = st_local("var1") var2 = st_local("var2") w=st_local("w") sampleVarName = st_local("touse_proj") linear_index = st_local("linear_index") V = st_data(.,(var1, var2,currvar),sampleVarName) varIn=V[.,3] if (w==""){ D = st_data(.,(var1, var2),sampleVarName) D = (D,J(rows(D),1,1)) } else { D = st_data(.,(var1, var2,w),sampleVarName) } V[.,3]=V[.,3]:*D[.,3] aux=sparse(V) Dy=rowsum(aux) Dy=Dy Ty=colsum(aux) Ty=Ty[1,1..cols(aux)-1]' //load the matrices from eresults if (save_to_e>0){ N=st_numscalar("e(dimN)") T=st_numscalar("e(dimT)") correction_rank=st_numscalar("e(rank_adj)") B=st_matrix("e(B)") } else{ //load the matrices from using option N=readMat(root,"twoWayN1") T=readMat(root,"twoWayN2") correction_rank=readMat(root,"twoWayCorrection") B=readMat(root,"twoWayB") st_numscalar("e(dimN)",N) st_numscalar("e(dimT)",T) st_numscalar("e(rank_adj)",correction_rank) } if (N0){ A=st_matrix("e(A)") invHH=st_matrix("e(invHH)") CinvHHDH=st_matrix("e(CinvHHDH)") } else{ A=readMat(root,"twoWayA") invHH=readMat(root,"twoWayinvHH") CinvHHDH=readMat(root,"twoWayCinvHHDH") } delta=A*Dy+B*Ty tau=B'*(Dy-CinvHHDH'*Ty)+(invHH:*Ty) \0 } else { if (save_to_e>0){ C=st_matrix("e(C)") invDD=st_matrix("e(invDD)") AinvDDDH=st_matrix("e(AinvDDDH)") } else{ C=readMat(root,"twoWayC") invDD=readMat(root,"twoWayinvDD") AinvDDDH=readMat(root,"twoWayAinvDDDH") } delta=(invDD:*Dy)+B*(Ty-AinvDDDH'*Dy) tau=B'*Dy+C*Ty \0 } varOut=(varIn-delta[V[.,1]]-tau[V[.,2]]):*sqrt(D[.,3]) st_store(st_data(.,linear_index,sampleVarName), newvar, varOut) } end program define twres, eclass version 11 syntax varlist(numeric ts fv) [using/], [Prefix(name)] [REPLACE] local varlist `varlist' local anything `varlist' foreach x of local anything { if strpos("`x'","."){ capt assert inlist( "`.'", "") local rc = !_rc if !_rc { di "{err} factor-variable and time-series operators not allowed, create the variables and then re-run the command" exit !_rc } } } foreach currvar of local varlist{ if ("`replace'"=="") { capture confirm variable `prefix'`currvar' local rc = !_rc if !_rc { di "{err} The variable `prefix'`currvar' already exists." exit !_rc } } } *in e(absorb) there is the fixed effects that we use to generate the new matrix V local absorb = "`e(absorb)'" gettoken var1 aux : absorb gettoken var2 twoway_w : aux local w `twoway_w' *set the vars to be projected gettoken depvar indepvars : varlist _fv_check_depvar `depvar' fvexpand `indepvars' qui{ tempvar touse_proj touse_check linear_index *set the sample that is projected gen byte `touse_proj'= e(sample) gen byte `touse_check' = `touse_proj' *touse_check is a marker of missing values of the vars projected markout `touse_check' `varlist' *check if there is a missing in some of the variables capture assert `touse_proj' == `touse_check' local rc = _rc } if `rc' { di "{err} Some of the included variables have missing values." exit `rc' } drop `touse_check' *check that there is using in the command or not. capt assert inlist( "`using/'", "") if !_rc { *check if e() has not been rewritten capt confirm scalar e(dimN) if _rc { di "{err} The e() has been rewritten, please run twset again." exit } scalar save_to_e=1 } else{ scalar save_to_e=0 mata microMataLoad() gettoken twoway_id: var1 gettoken twoway_t: var2 gettoken twoway_w: w qui{ tempvar touse_proj touse_proj2 touse_proj3 mark `touse_proj2' `if' `in' markout `touse_proj2' `twoway_id' `twoway_t' `twoway_w' *Discard the observations with negative weights if !("`twoway_w'"==""){ replace `twoway_w' = . if `twoway_w'<=0 replace `touse_proj2' = 0 if `twoway_w' == . } tempvar touse_set2 nonredundants `twoway_id' `twoway_t' if `touse_proj2', gen(`touse_proj') } gen `touse_proj3'=`touse_proj2' ereturn post, esample(`touse_proj3') ereturn local absorb "`var1' `var2' `twoway_w'" ereturn scalar dimN= e(dimN) ereturn scalar dimT= e(dimT) ereturn scalar rank_adj=e(rank_adj) } *variable created to store only the observations that are non-missings and in that way the arrays are conformables gen `linear_index' = _n *we create the new variables, if a variable already exists then it is ignored and not projected foreach currvar of local varlist { local newvar="`prefix'`currvar'" if ("`replace'" != "") { local newvar="`currvar'" mata projVar() } else { capture confirm variable `prefix'`currvar', exact if !_rc { } else{ qui gen `newvar'=. mata projVar() } } } end