*! version 1.0.0 14sep1998  statalist distribution
program define grand2
	version 5.0
	local options "Level(integer $S_level)"
	parse "`*'", parse(",")
	if "`1'" == "" | "`1'" == "," {
		if "$S_E_cmd" != "grand2" {
			error 301
		}
		parse "`*'"
	}
	else {

		if "$S_E_cmd" != "fit" { error 301 }

		/* Store off information from fit */

		local obs0 = _result(1)
		local dof0 = _result(5)
		local depvar0 $S_E_depv

		local varlist "req existing"
		local options "Level(integer $S_level)"
		parse "`*'"
		parse "`varlist'", parse(" ")

		local depv $S_E_depv

		/* prepare to handle weight */

		tempvar weight touse
		if "$S_E_exp" != "" {
			gen double `weight' $S_E_exp
		}
		else    gen byte `weight' = 1

		/* establish the sample */

		mark `touse' $S_E_if $S_E_in [$S_E_wgt $S_E_exp]
		markout `touse' $S_E_vl

		/* check if the indicators fully and exactly span the space */

		tempvar one
		egen byte `one' = rsum(`varlist')
		capture assert `one' == 1 if `touse'
		if _rc != 0 {
disp in blue "Warning, indicators `varlist' do not full span the space"
		}

		/* build the contrast matrix */

		tempname b0 V0 b V C catwt N

		matrix `b0' = get(_b)
		matrix `V0' = get(VCE)
					/* Note, relying on _cons being
					 * in b0 and V0 -- if what get()
					 * returns is changed in future, these
					 * need to be padded w/ one more
					 * row/column of 0's */

		local colnams : colnames(`b0')

		local k0 = colsof(`b0')
		matrix `C' = I(`k0')
		matrix colnames `C' = `colnams'
		matrix rownames `C' = `colnams'

		qui sum `weight' if `touse', meanonly
		scalar `N' = _result(18)

		IndexLst "`varlist'" "`colnams'"
		local collist $S_2
		local k : word count `varlist'

		local i 1
		while "``i''" != "" {
			local col : word `i' of `collist'
			qui sum `weight' if `touse' & ``i'' == 1, meanonly
			scalar `catwt' = _result(1) / `N'
			scalar `catwt' = _result(18) / `N'

			local j 1
			while `j' <= `k' {
				local row : word `j' of `collist'
				if `row' == `col' {
					matrix `C'[`row' , `col'] = 1 - `catwt'
				}
				else    matrix `C'[`row' , `col'] = -`catwt'
				local j = `j' + 1
			}
			matrix `C'[`k0' , `col'] = `catwt'

			local i = `i' + 1
		}

		/* Compute linear combination using the contrast matrix */

		mat `b' = `b0'*`C''
		mat `V' = `C'*`V0'
		mat `V' = `V'*`C''

		mat post `b' `V', obs(`obs0') dof(`dof0') depname(`depvar0')

		global S_E_cmd "grand2"
	}

	/* Display results */


	di in gr _n "Estimates as grand mean/intercept and marginal impacts" _n
	matrix mlout, level(`level')
	di in gr "Note:  The grand mean is the coefficient of _cons"

end

program define IndexLst /* toklist list */ /* returns list of indexes in S_2 */
	local toklist "`1'"
	local list    "`2'"

	global S_2
	parse "`toklist'", parse(" ")
	local i 1
	while "``i''" != "" {
		Index "``i''" "`list'"
		global S_2 "$S_2 $S_1"
		local i = `i' + 1
	}
end

program define Index /* token list */ /* returns index in S_1 */
	local token "`1'"
	local list  "`2'"

	global S_1 = 0

	parse "`list'", parse(" ")
	local i = 1
	while "``i''" != "" {
		if "`token'" == "``i''" {
			global S_1 `i'
			exit
		}
		local i = `i' + 1
	}
end