*! xtset2 1.1 - June 2020 *! author Jan Ditzen *! www.jan.ditzen.net - j.ditzen@hw.ac.uk *! see viewsource xtset2.ado for more info. /* xtset2 extends xtset. Version history 1.0 to 1.1 - bug fix in svmat .. ,name(); adds a "1" to the name, fixed. */ version 11.1 capture program drop xtset2 program define xtset2, rclass syntax [varlist(numeric default=none)] [if], [* checkvars(varlist) matrix showxtset version] if "`version'" != "" { display "xtset2, version 1.0" return scalar version = 1 } else { qui{ if "`varlist'" == "" { _xt local varlist "`r(ivar)' `r(tvar)'" } preserve *noi disp "`if'" if "`if'" != "" { keep `if' } tokenize `varlist' local idvar "`1'" local tvar "`2'" **Obtain N amd N_g local N = _N tempvar N_gtmp N_gtmp2 egen `N_gtmp' = tag(`idvar') egen `N_gtmp2' = total(`N_gtmp') sum `N_gtmp2' , meanonly local N_g = r(mean) local N = r(N) **Determine type of balance if "`checkvars'" == "" { local checkvars "`idvar' `tvar'" } /* 1) T = Ti (same number of periods) 2) Tmin = Tmin_i & Tmax = Tmax_i (beginning and end the same) 3) T(i) = T(j), where T(t)_i = T(t)_j (i and j have same periods) 4) no gaps 5) no missings in variables for strongly balanced 1,2, 3 and 4 have to hold for weakly balanced 1 and 2 or 1 and 3 or 1 and 4 have to hold rest unbalanced */ local Cond1 = 0 local Cond2 = 0 local Cond2Max = 0 local Cond2Min = 0 local Cond3 = 0 local Cond4 = 0 local Cond5 = 0 ** check 1) tempvar Ttot by `idvar', sort: gen `Ttot' = _N inspect `Ttot' if `r(N_unique)' == 1 { local Cond1 = 1 } ** Check 2) tempvar Tmin Tmax by `idvar', sort: egen `Tmax' = max(`tvar') by `idvar', sort: egen `Tmin' = min(`tvar') inspect `Tmax' if `r(N_unique)' == 1 { local Cond2Max = 1 } inspect `Tmin' if `r(N_unique)' == 1 { local Cond2Min = 1 } **set dummy if `Cond2Max' == 1 & `Cond2Min' == 1 { local Cond2 = 1 } ** Check 3) tempname Tmat tab `tvar' , matcell(`Tmat') svmat `Tmat' , name(`Tmat') inspect `Tmat'1 if `r(N_unique)' == 1 { local Cond3 = 1 } ** Check 4), ** check if gaps tempvar gaps by `idvar' (`tvar'), sort: gen `gaps' = `tvar' - `tvar'[_n-1] by `idvar' (`tvar'), sort: replace `gaps' = `gaps'[_n+1] if _n == 1 inspect `gaps' if `r(N_unique)' == 1 { local Cond4 = 1 } **count gaps sum `Tmat'1 scalar NumGaps = (r(max) - r(mean))*r(N) ** check 5) tempvar Obsmissing Obsmissingtotal egen `Obsmissing' = rowmiss(`checkvars') by `idvar', sort: egen `Obsmissingtotal' = total(`Obsmissing') sum `Obsmissingtotal' if `r(mean)' == 0 { local Cond5 = 1 } **number of missings sum `Obsmissing' local NumMissing = r(sum) **stats for time periods tempvar tvarcount by `idvar', sort: egen `tvarcount' = count(`tvar') sum `tvarcount' scalar meanT = r(mean) scalar minT = r(min) scalar maxT = r(max) **Determine which balanced type local balanced = "unbalanced" local balancedN = 1 *noi disp "1: `Cond1' , 2: `Cond2' , 3: `Cond3' , 4: `Cond4'" if `Cond1' == 1 & `Cond2' == 1 & `Cond3' == 1 & `Cond4' == 1 & `Cond5' == 1 { local balanced = "strongly balanced" local balancedN = 2 } else if (`Cond1' == 1 & `Cond2' == 1) | (`Cond1' == 1 & `Cond3' == 1) | (`Cond1' == 1 & `Cond4' == 1) { local balanced = "weakly balanced" local balancedN = 3 } *else if `Cond1' == 1 & `Cond2' == 1 & `Cond3' == 0 { * local balanced = "weakly balanced" * local balancedN = 3 *} if "`matrix'" != "" { collapse (count) `var'T = `tvar' (min) `tvar'min=`tvar' (max) `tvar'max=`tvar' (mean) `tvar'bar=`tvar' (max) `Obsmissingtotal'miss=`Obsmissingtotal' , by(`idvar') mkmat `idvar' `var'T `tvar'min `tvar'max `tvar'bar `Obsmissingtotal'miss , matrix(PanelMatrix) matrix colnames PanelMatrix = Panelid T Tmin Tmax Tbar Missings } restore } qui capture _xt local rc = _rc if `rc' != 0 | "`options'" != "" { disp "xtset2 output:" } di as txt _col(8) "panel variable: " as res "`idvar' (`balanced')" di as txt _col(6) "number of groups: " as res "`N_g'" di as txt _col(8) "number missing: " as res "`NumMissing'" di as txt _col(11) "number gaps: " as res NumGaps di as txt _col(13) "variables: " as res "`checkvars'" if `balancedN' == 1 { di "" di as txt _col(10) "number of periods" di as txt _col(15) "average: " as res meanT di as txt _col(19) "Min: " as res minT di as txt _col(19) "Max: " as res maxT } else { di as txt _col(5) "number of periods: " as res meanT } **check if data is xtset, if not, set it if `rc' != 0 | "`options'" != "" { disp "" disp "xtset output:" xtset `idvar' `tvar' , `options' } return add return local balanced = "`balanced'" return scalar N_g = `N_g' return scalar balancedN = `balancedN' return scalar NumMissing = `NumMissing' return scalar NumGaps = NumGaps return scalar Tmin = minT return scalar Tmean = meanT return scalar Tmax = maxT return scalar N = `N' return local panelvar "`idvar'" return local timevar "`tvar'" if "`matrix'" != "" { return matrix PanelMatrix = PanelMatrix } } end