*! improved xtsum function
*! based on stata xtsum version 1.0.7  04sep2000
program define xtsumcorr, rclass byable(recall) sort
	version 6
	syntax [varlist] [if] [in] [, I(varname)]
	xt_iis `i'
	local ivar "`s(ivar)'"

	tempname N n Tbar mean sdo min max sdb sdw minb maxb minw maxw
	tempname sdbcor sdwcor rho
	tempvar touse tu bv wv Ti
	mark `touse' `if' `in'

	di in smcl in gr _n "Variable" _skip(9) "{c |}" _skip(6) /*
	*/ "Mean   Std. Dev.       Min        Max {c |}    Observations" /*
	*/ _n "{hline 17}{c +}{hline 44}{c +}{hline 16}"

	sort `ivar'
	tokenize `varlist'
	while "`1'"!="" {
		quietly {
			gen byte `tu' = `touse' & `1'!=.
			summ `1' if `tu'
			scalar `N' = r(N)
			scalar `mean' = r(mean)
			scalar `sdo'  = cond(`N'>1,sqrt(r(Var)),.)
			scalar `min'  = r(min)
			scalar `max'  = r(max)
			by `ivar': gen long `Ti' = /*
				*/ cond(_n==_N,sum(cond(`tu',1,0)),.)
			by `ivar': gen double `bv'= cond(_n==_N, /*
				*/ sum(cond(`tu',`1',0)) / `Ti', . )
			summ `Ti' if `tu'
			* scalar `Tbar' = cond(r(mean)==.,0,r(mean))
			if r(min)==r(max) {	/* min == max */
				local wrd "    T"
			}
			else	local wrd "T-bar"
			drop `Ti'
			by `ivar': gen double `wv' = /*
				*/ cond(`tu',`1'-`bv'[_N], .) /* + `mean' */
		}
		#delimit ;
		di in smcl in gr /*
			*/ abbrev("`1'",8) _col(10) "overall {c |} " in ye
			%9.0g `mean' "  "
			%9.0g `sdo' "  "
			%9.0g `min' "  "
			%9.0g `max' in gr " {c |}"
			_col(69) "N =" %8.0f `N' ;
		qui summ `bv' ;
		scalar `n' = r(N) ;
		scalar `sdb' = cond(`n'>1,sqrt(r(Var)),.) ;
		scalar `minb' = r(min) ;
		scalar `maxb' = r(max) ;

		* Now make between printout ;
		di in smcl in gr _col(10) "between {c |}" _col(31) in ye
			%9.0g `sdb' "  "
			%9.0g `minb' "  "
			%9.0g `maxb' in gr " {c |}"
			_col(69) "n =" %8.0f `n' ;

		qui summ `wv' ;
		scalar `sdw' = cond(r(N)>1,sqrt(r(Var)),.) ;
		scalar `minw' = r(min) + `mean' ;
		scalar `maxw' = r(max) + `mean' ;
		scalar `Tbar' = `N'/`n' ;

		* Now make within printout ;
		di in smcl in gr _col(10) "within  {c |}" _col(31) in ye
			%9.0g `sdw' "  "
			%9.0g `minw' "  "
			%9.0g `maxw' in gr
			" {c |} `wrd' =" %8.0g `Tbar' ;

		* Now compute corrected between and within sd's ;
		scalar `sdwcor' = `sdw'*sqrt((`N'-1)/(`N'-`n')) ;
		scalar `sdbcor' = sqrt(`sdo'*`sdo' - `sdwcor'*`sdwcor') ;
		scalar `rho' = (`sdbcor'*`sdbcor')/(`sdo'*`sdo') ;
		* Now make corrected between and within printouts ;
		di in smcl in gr _col(4) "corr. between {c |}" _col(31) in ye
			%9.0g `sdbcor' "                      "
			in gr " {c |}" ;

		di in smcl in gr _col(4) "corr. within  {c |}" _col(31) in ye
			%9.0g `sdwcor' "                      "
			in gr " {c |}" ;
		di in smcl in gr _col(4) "      rho     {c |}" _col(31) in ye
			%6.0g `rho'    "  (betw. fract. of total)"
			in gr " {c |}" ;

		#delimit cr
		drop `wv' `bv' `tu'

		ret scalar N     = `N'
		ret scalar n     = `n'
		ret scalar Tbar  = `Tbar'
		ret scalar mean  = `mean'
		ret scalar sd    = `sdo'
		ret scalar min   = `min'
		ret scalar max   = `max'
		ret scalar sd_b  = `sdb'
		ret scalar min_b = `minb'
		ret scalar max_b = `maxb'
		ret scalar sd_w  = `sdw'
		ret scalar min_w = `minw'
		ret scalar max_w = `maxw'

		* double saves
		scalar S_1 = `N'
		scalar S_2 = `n'
		scalar S_3 = `Tbar'
		scalar S_4 = `mean'
		scalar S_5 = `sdo'
		scalar S_6 = `min'
		scalar S_7 = `max'
		scalar S_8 = `sdb'
		scalar S_9 = `minb'
		scalar S_10= `maxb'
		scalar S_11 = `sdw'
		scalar S_12 = `minw'
		scalar S_13 = `maxw'

		mac shift
		if "`1'"!="" {
			di in smcl in gr _col(18) "{c |}" _col(63) "{c |}"
		}
	}
end
exit