📄 xtabond.ado
字号:
tempname p m Ti_max Ti_obs Ti_min
tempname W A b yi Zy maxl2
/* Do this for all individuals, regardless of touse status
the internal routines will drop ids for which the sum of touse
is zero
*/
local q = `lags' + 1
local tau =`tmax'-`tmin'+1
local t0 = `tmin'+`q'
if `maxldep' <0 {
di as err "maxldep must be strictly greater than zero."
exit 198
}
if `maxldep'==0 {
scalar `maxl2'=`tau'-1
local maxldep2 = `tmax'-`tmin'-1
}
else {
scalar `maxl2'=`maxldep'
local maxldep2 = `maxldep'
}
/* update depvar and predetermined matrices */
tempname dargmat
mat `dargmat'=(`lags', `maxl2')
if "`preM2'" != "" {
mat `preM2' =`dargmat' \ `preM2'
}
else {
tempname preM2
mat `preM2' = `dargmat'
}
local prows = rowsof(`preM2')
/* substitute out time-series operators in laglist indeps prevars */
if "`laglist'" != "" {
tsrevar `laglist' if `touse', substitute
local laglist "`r(varlist)'"
}
tsrevar `indeps' if `touse', substitute
local indeps "`r(varlist)'"
tsrevar `prevars' if `touse', substitute
local prevars "`r(varlist)'"
markout `touse' `laglist' `indeps' `depvar' `prevars' `inst_o'
qui sum `touse'
if r(max) == 0 {
di as err "no observations"
exit 2000
}
tempvar l2touse
qui gen byte `l2touse'= (L`lags'D.`depvar' < . & `touse' )
/* Make position and absolute id variables */
tempvar inobs abid inobs2 pos0 posa
tempname tobs_min tobs_max tobs_av id2max_t
tempvar abid2
qui gen long `posa' = _n
qui by `id': gen long `pos0'= `posa'[1] if _n > 1
qui gen long `inobs' = 1 if `l2touse'
qui by `id': replace `inobs' = sum(`inobs')
qui by `id': replace `inobs' = `inobs'[_N] if _n < _N
qui sum `inobs' if `t2'==1, meanonly
/* max holds Ti_max, min holds Ti_min and mean holds Ti_mean */
/* Generate and summarize absolute id */
qui by `id': gen `inobs2' = ( `inobs' > 0 & _n == 1 )
qui sort `inobs2' `id' `t'
qui gen long `abid' = sum(`inobs2') if `inobs2' > 0
qui sum `abid' , meanonly
/* max hold max absolute id */
scalar `id2max_t'= r(max)
local id2max = r(max)
qui sort `id' `t'
qui by `id': replace `abid' = `abid'[1] if _n >1
qui by `id': gen `abid2'=1 if _n==1
qui replace `abid2' = sum(`abid2')
qui by `id': replace `abid2'=`abid2'[1] if _n>1
qui sum `abid2', meanonly
local abid2m = r(max)
qui sum `inobs' if `t2'==1 & `inobs' > 0, meanonly
/* max holds Ti_max, min holds Ti_min and mean holds Ti_mean */
scalar `tobs_min' = r(min)
scalar `tobs_max'=r(max)
scalar `tobs_av'=r(mean)
/* Make zvars and wvars */
/* when finished you can read the instruments from the macros
* zivars, timac and lvmac. These macros form a parallel list
* data structure. Each three tuple describes a valid instrument:
* zivar element at absolute time timac element lagged lvmac element
* is a valid instrument
*
*/
local wvars
local zivars
local timac
local lvmac
/* cope with five types of variables,
* depvar, pred/endog, exog, already differenced variables, extra insts
* in this order adding to wvars as appropriate
*/
/* i is counter over moment conditions (variables) created
* cutcols is counter over columns removed because of missing data
* totcc is counter over moment conditions removed because of missing
* data */
local i 1
/* depvar section
*/
if `lags' >0 {
tsunab ad2w : l(1/`lags')d.`depvar'
local wvars "`wvars' `ad2w'"
}
/* if laged depvars gen moment variables and put moment vars into zvars */
/* begin new version for depvars */
if `lags' > 0 {
forvalues ti=`t2min'/`t2max' {
local newrow 1
qui sum `touse' if `t2' == `ti', meanonly
if r(max) == 1 {
local lmax = `lags' + `ti'-`t2min'
forvalues al = `lmax'(-1)1 {
if `al' <= `maxldep2' {
local al2= `al' + 1
qui count if (L`al2'.`depvar' < . & `ti'== `t2' & `l2touse')
if r(N) > 0 {
local zivars `zivars' `depvar'
local timac `timac' `ti'
local lvmac `lvmac' `al2'
local i = `i' +1
}
}
}
}
}
}
/* end new version for depvars */
/* pre/endog section
* parse and add to wvars and zvars
*/
local pre `prelist'
while "`pre'" != "" {
gettoken tok pre : pre , parse(":")
gettoken colon pre : pre , parse(":")
if "`colon'" != ":" {
di as err "internal xtabond error, pre_info invalid"
exit 498
}
gettoken pvars tok : tok , parse(",")
tsunab pvars2 : `pvars'
gettoken comma tok : tok , parse(",")
if "`comma'" != "," {
di as err "internal xtabond error, pre_info "/*
*/"options invalid"
exit 498
}
gettoken pdlags tok : tok
// pdlags is the number of lags in the model for these pvars
capture confirm integer number `pdlags'
if _rc>0 {
di as err "internal xtabond error, pre_lags invalid"
exit 498
}
gettoken pdmlags tok : tok
capture confirm integer number `pdmlags'
// pdmlags is the maximum number of lags that can be used as instruments
// for these pvarvs
if _rc>0 {
di as err "internal xtabond error, pre_mlags invalid"
exit 498
}
// pdfirst is the first lag that can be used as an instrument minus one
gettoken pdfirst tok : tok
capture confirm integer number `pdfirst'
if _rc>0 {
di as err "internal xtabond error, pre_first invalid"
exit 498
}
if `pdfirst' <0 {
di as err "internal xtabond error, pre_first less " ///
"than zero"
exit 498
}
tsunab wtmp2 : dl(0/`pdlags').(`pvars2')
local wvars `wvars' `wtmp2'
local pdfinst = `pdfirst' + 1
/* pdfinst = 1 with endog
* and
* pdfinst = 0 with pred
*/
foreach pvarb of local pvars2 {
forvalues ti=`t2min'/`t2max' {
local newrow 1
qui sum `touse' if `t2' == `ti', meanonly
if r(max) == 1 {
local plmax = `lags' + `ti' - `t2min'
forvalues al = `plmax'(-1)`pdfirst' {
if `al' < `pdmlags' ///
+ `pdlags' {
local al2 = `al' + 1
qui count if (L`al2'.`pvarb' < . & `ti'== `t2' & `l2touse')
if r(N) > 0 {
local zivars `zivars' `pvarb'
local timac `timac' `ti'
local lvmac `lvmac' `al2'
local i = `i' +1
}
}
}
}
}
}
}
/* now add on inst() variables to zvars
* note inst vars are not transformed by program, must be transformed
* by user
*/
local instmac `inst'
/* exogenous variable section
* contains already differenced variables
* already diff vars have not been diffd, other exog variable were
* explicitly diffd in main code.
*/
local indmac `indeps'
if "`indeps'" != "" {
local wvars `wvars' `indeps'
}
local cnt 1
foreach wv of local wvars {
tempvar wv2`cnt'
qui gen double `wv2`cnt'' =cond(`l2touse', `wv', 0)
local wvars2 `wvars2' `wv2`cnt''
local cnt = `cnt' + 1
}
local wvmac `wvars2'
/* Done making zvars and wvars */
tempname dd
qui gen double `dd'= D.`depvar' if `l2touse'
local wvcnt : word count `wvmac'
local zvcnt : word count `zivars'
local indcnt : word count `indmac'
local instcnt : word count `instmac'
tempname zimat hzname zitname hztname tmpm1
_xtzw `dd', zwname(`W') aname(`A') zyname(`Zy') ivar(`abid') /*
*/ imax(`id2max') tvar(`t2') tmin(`t2min') /*
*/ tmax(`t2max') lags(`lags') touse(`l2touse') /*
*/ zivars(zivars) timac(timac) lvmac(lvmac) /*
*/ indmac(indmac) instmac(instmac) wvmac(wvmac) /*
*/ wwords(`wvcnt') zwords(`zvcnt') indwords(`indcnt') /*
*/ instwords(`instcnt') zimat(`zimat') hzname(`hzname')/*
*/ zitname(`zitname') hztname(`hztname')
mat `W'=`W''
local zcols = colsof(`W')
qui count if `l2touse' == 1
local n2 = r(N)
tempvar touses
mark `touses' if `t2'>`q'
markout `touses' `laglist' `indeps'
mat `A'=syminv(`A')
tempname M1 V sig b
mat `M1'=(`W'*`A'*`W'')
mat `tmpm1' = .5*(`M1'' + `M1')
if mreldif(`tmpm1', `M1') > 1e-5 {
di as err "onestep-naive VCE is not symmetric"
exit 498
}
mat `M1' = `tmpm1'
mat `M1'=syminv(`M1')
mat `b'=`M1'*`W'*`A'*`Zy'
mat `b'=`b''
tokenize `fvarlist'
macro shift
local names "`*'"
local k: word count `names'
mat colnames `b'=`names'
tempname M1t sig1
mat `V'=`M1'
mat `M1t'=`M1'
mat colnames `M1t'=`names'
mat rownames `M1t'=`names'
est post `b' `M1t'
tempvar xb res1 res2
qui _predict double `xb', xb
qui gen double `res1'=D.`depvar'-`xb' if `touse'
qui gen double `res2'=`res1'^2 if `touse'
qui summ `res2' if `touse'
scalar `sig'=r(sum)
local NT =r(N)
tempvar N_idv
qui gen long `N_idv'=(`res1' <. )
qui by `id': replace `N_idv'= sum(`N_idv') if `touseb'
qui by `id': replace `N_idv'=. if _n<_N & `touseb'
qui by `byvars' `id': replace `N_idv'=cond(_n==1,(`N_idv'[_N]>0),.)
qui replace `res1'=0 if `res1'>=.
scalar `sig1'=`sig'/(`NT'-`k')
if "`twostep'" == "" {
if "`robust'" != "" {
tempname A2 hzname
_xta2 `res1', a2name(`A2') ivar(`abid') /*
*/ imax(`id2max') tvar(`t2') tmin(`t2min') /*
*/ tmax(`t2max') lags(`lags') touse(`l2touse') /*
*/ zivars(zivars) timac(timac) lvmac(lvmac) /*
*/ indmac(indmac) instmac(instmac) /*
*/ zwords(`zvcnt') indwords(`indcnt') /*
*/ instwords(`instcnt') zimat(`zimat') /*
*/ hzname(`hzname')
mat `V'=`M1'*`W'*`A'*`A2'*`A'*`W''*`M1'
}
else {
scalar `sig'=`sig'/(`NT'-`k')
mat `V'=`sig'*`V'
}
local names "`namesf'"
mat `b'=e(b)
mat colnames `b'=`names'
mat colnames `V'=`names'
mat rownames `V'=`names'
}
else {
tempname A2 V H V_1r b_1 hzname
_xta2 `res1', a2name(`A2') ivar(`abid') /*
*/ imax(`id2max') tvar(`t2') tmin(`t2min') /*
*/ tmax(`t2max') lags(`lags') touse(`l2touse') /*
*/ zivars(zivars) timac(timac) lvmac(lvmac) /*
*/ indmac(indmac) instmac(instmac) /*
*/ zwords(`zvcnt') indwords(`indcnt') /*
*/ instwords(`instcnt') zimat(`zimat') /*
*/ hzname(`hzname')
mat `V_1r'=`M1'*`W'*`A'*`A2'*`A'*`W''*`M1'
mat `b_1'=e(b)
mat `A2' = syminv(`A2')
mat `M1'=(`W'*`A2'*`W'')
mat `tmpm1' = .5*(`M1'' + `M1')
if mreldif(`tmpm1', `M1') > 1e-5 {
di as err "two-step VCE is not symmetric"
exit 498
}
mat `M1' = `tmpm1'
mat `M1'=syminv(`M1')
mat `b'=`M1'*`W'*`A2'*`Zy'
mat `b'=`b''
local names "`namesf'"
local k: word count `names'
mat colnames `b'=`names'
mat `V'=`M1'
mat colnames `M1'=`names'
mat rownames `M1'=`names'
mat colnames `V_1r'=`names'
mat rownames `V_1r'=`names'
est post `b' `M1'
mat `M1'=`V'
tempvar xb res res2
tempname sig
qui _predict double `xb' if `touses' , xb
qui gen double `res'=D.`depvar'-`xb'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -