*! version 1.1.5 24sep2008 C F Baum / Fabian Bornhorst * Andrew Levin, Chien-Fu Lin, Chai-Shang James Chu, * J. Econometrics 2002, 108, 1-24 (LLC) * Andrew Levin and Chien-Fu Lin, Unit Root Tests in Panel Data: New Results, * UCSD DP 93-56 * v1.0.1 : 2A20 cfb Corrections indicated by Gene Liang in demeaning, calc * LR variance, correction factor table lookup * v1.1.1 : 4B14 cfb Correction for Andrews truncation rule * v1.1.2: 4B29 cfb Trap zero unit variation * v1.1.3: 5C02 cfb Correction to zero unit variation logic * v1.1.4: 6618 cfb Correction to make case tempname, change subroutine call accordingly * v1.1.5: 8924 cfb Correction to index demeaned vars by panel unit rather than panelvar code program define levinlin, rclass version 7.0 syntax varname(ts) [if] [in] , Lags(numlist int >=0) [ Trend noConstant ] qui tsset local id `r(panelvar)' local time `r(timevar)' tempname case if "`constant'" != "" & "`trend'" == "" { scalar `case'=1 local det ",noc" local text "none" } else if "`constant'" == "" & "`trend'" == "" { scalar `case'=2 local text "constant" } else if "`constant'" == "" & "`trend'" != "" { scalar `case'=3 local text "constant & trend" } else { di in red "You cannot choose trend and no constant!" error 198 } di in gr _n "Levin-Lin-Chu test for " in ye "`varlist'" _col(35) in gr "Deterministics chosen: " in ye "`text'" marksample touse markout `touse' `time' tsreport if `touse', report panel if r(N_gaps) { di in red "sample may not contain gaps" error 198 } qui xtsum `time' if `touse' // N: number of panel units local N `r(n)' local T `r(Tbar)' if int(`T')*`N' ~= r(N) { di in red "panel must be balanced" error 198 } local tmin `r(min)' local tmax `r(max)' local npi : word count `lags' tempname Vals tempvar eps epstil vl vltil hold dy dy2 vvar * copy variable to prevent alteration and allow ts ops qui gen double `vvar' = `varlist' if `touse' if "`trend'" ~= "" { local trend "`time'" } * remove common time effects per LLC p.13 forv t = `tmin'/`tmax' { qui { su `vvar' if `time' == `t' & `touse' /*, meanonly */ replace `vvar' = `vvar' - r(mean) if `time' == `t' & `touse' } } * 4B29 corr 5C02: guard against no unit variation qui su `vvar' if abs(r(sd))<1d-10 { di as err _n "Error: no variation across units." error 2000 } * 2A20: relocate generating lags here to ensure that the lagged variables * correspond to the time-demeaned variable // single lag common to all panel units if `npi' == 1 { forv i=1/`N' { local ps`i' = `lags' if `lags' > 0 { local tps`i' "L(1/`lags')D.`vvar'" } } scalar lavg = `lags' } else if `npi' ~= `N' { di in r "Error: For `N' panel units, either 1 or `N' lag lengths must be specified" error 198 } else { scalar lavg = 0 // lag specified for each panel unit forv i = 1/`N' { local ps`i' : word `i' of `lags' if `ps`i'' > 0 { local tps`i' "L(1/`ps`i'')D.`vvar'" scalar lavg = lavg + `ps`i'' } } scalar lavg = lavg / `N' } * define unit identifier qui tab `id' if `touse', matrow(`Vals') local nvals = r(r) /* 4B29: mod to forv per NJC local i = 1 while `i' <= `nvals' { local val = `Vals'[`i',1] local vals "`vals' `val'" local i = `i' + 1 } */ forv i = 1/`nvals' { local val = `Vals'[`i',1] local vals "`vals' `val'" } qui { gen double `eps' = . gen double `epstil' = . gen double `vl' = . gen double `vltil' = . gen double `dy' = . gen double `dy2' = . } scalar ttil = `T' - lavg - 1 scalar sn = 0 scalar vn = 0 * LL truncation (p. 24, due to Andrews) local trunc = int(3.21*((ttil)^(1/3))) * 4A11: guard against insufficient obs. if (`trunc' > `T'-3) { local trunc = `T'-3 di in r "Reducing Andrews truncation" } * double Bartlett weights, div by (asy) T-1 forv i=1/`trunc' { scalar w`i' = 2.0/(`T'-1)*(1.0-(`i'/(`trunc'+1))) } // di as err "vals `vals'" local jpan 0 foreach i of local vals { qui { * LLC eqn 2 (LL eqns 2, 3, 4) // corr 8924: must reference number of panel unit rather than panelvar value local ++jpan // noi di as err "*** `i' `jpan' `tps`jpan''" // noi su D.`vvar' `tps`jpan'' `trend' if `id'==`i' & `touse' /*noi*/ reg D.`vvar' `tps`jpan'' `trend' if `id' == `i' & `touse' `det' capt drop `hold' predict double `hold' if e(sample), r replace `eps' = `hold' if e(sample) /*noi*/ reg L.`vvar' `tps`jpan'' `trend' if `id' == `i' & `touse' `det' capt drop `hold' predict double `hold' if e(sample), r replace `vl' = `hold' if e(sample) * (LLC eqn 4 (LL eqns 5, 6, 7) regress `eps' `vl' if e(sample), noc scalar se`i' = e(rmse) replace `epstil' = `eps' / se`i' if e(sample) replace `vltil' = `vl' / se`i' if e(sample) * LLC eqn 5 (LL eqn 8, term 1): rewritten 2A21 if `case'==1 { replace `dy' = D.`vvar' if `id' == `i' & `touse' } else if `case'==2 { su D.`vvar' if `id' == `i' & `touse', meanonly replace `dy' = D.`vvar' - r(mean) if `id' == `i' & `touse' } else if `case'==3 { reg D.`vvar' `time' if `id' == `i' & `touse' capt drop `hold' predict double `hold' , r replace `dy' = `hold' if e(sample) } replace `dy2' = `dy'^2 if `id' == `i' & `touse' su `dy2' if `id' == `i' & `touse',meanonly scalar s2y`i' = r(mean) * LLC eqn 5 (LL eqn 8 term 2) /* set trace on di in r "`trunc' `i'" noi su `dy' if `id' == `i' & `touse' */ forv l=1/`trunc' { mat accum dd = `dy' L`l'.`dy' if `id' == `i' & `touse', noc scalar s2y`i' = s2y`i' + w`l'* dd[2,1] } scalar sy`i' = sqrt(s2y`i') * LLC eqn 6 (LL eqn 9) scalar s`i' = sy`i'/se`i' scalar ess2 = se`i'^2 * noi di "`i' " " " ess2 " " s2y`i' scalar sn = sn + s`i' * scalar vn = sn + s`i'*s`i' } } * LL eqn 10 scalar sn = sn/`N' * scalar vn = vn/`N' * LLC eqn 8 (LL eqn 11): calculate sige, rse with large-sample divisor // su `epstil' `vltil' qui regress `epstil' `vltil', noc scalar sige = e(rmse)*sqrt(e(df_r)/e(N)) scalar delta = _b[`vltil'] matrix v = e(V) scalar rse = sqrt(v[1,1]*e(df_r)/e(N)) scalar tee = delta/rse * LLC eqn 12 (LL eqn 16) _getLL, case(`case') ttil(ttil) * di "N, ttil, sn, sige, rse, r(mustar) `N' " ttil " " sn " " sige " " rse " " r(mustar) * di "tee, r(sigstar)" tee " " r(sigstar) scalar tstar = (tee - `N'*ttil*sn/(sige^2)*rse*r(mustar))/r(sigstar) * 2A21: calculate as signed scalar pval = norm(tstar) noi di in gr _n "Pooled ADF test, N,T = (`N',`T')" /* */ _col(35) "Obs = " e(N) _col(48) _n "Augmented by " lavg " lags (average) " /* */ _col(35) "Truncation: `trunc' lags" noi di in gr _n "coefficient" _col(16) "t-value" _col(31) "t-star" _col(44) "P > t" noi di in ye %9.5f delta _col(14) %9.3f tee _col(26) /* */ %11.5f tstar _col(40) %9.4f pval return scalar nobs=e(N) return scalar N=`N' return scalar T=`T' return scalar delta=delta return scalar tstar=tstar return scalar pval=pval return scalar lavg=lavg return local trunc=`trunc' return local lags `lags' return local determ `text' end program define _getLL, rclass syntax , Case(string) Ttil(string) * args kayse ttil tempname ss msda * LL Table 2, mean and std dev adjustments (corr 2A21 for equality) mat `ss' = ( 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 250, 999999) if `case' == 1 { mat `msda' = ( 0.004, 0.003, 0.002, 0.002 , 0.001, 0.001, 0.001, 0, 0, 0, 0, 0, 0\ /* */ 1.049, 1.035, 1.027, 1.021, 1.017, 1.014, 1.011, 1.008, 1.007, 1.006, 1.005, 1.001, 1.000) } if `case' == 2 { mat `msda' = (-.554,-.546,-.541,-.537,-.533,-.531,-.527,-.524,-.521, -.520,-.518,-.509,-.500 \ /* */ .919,.889,.867,.85,.837,.826,.810,.798,.789,.782,.776,.742,.707) } if `case' == 3 { mat `msda' = (-.703,-.674,-.653,-.637,-.624,-.614,-.598,-.587,-.578,-.571, -.566,-.533,-.500 \ /* */ 1.003,.949,.906,.871,.842,.818,.780,.751,.728,.710,.695,.603,.500) } forv i=1/13 { if `ttil' <= `ss'[1,`i'] { return scalar mustar = `msda'[1,`i'] return scalar sigstar = `msda'[2,`i'] continue,break } } end