*! version 4.0.0 PR 26Oct95.
program define contrast
	version 4.0
	local varlist "req ex min(2)"
	local if "opt"
	local in "opt"
	#delimit ;
	local options "MEans COEFfs(string) TRend ADjust
 LEvel(integer $S_level) *" ;
	#delimit cr
	parse "`*'"
	if "`coeffs'"=="" & "`trend'"=="" {
		di in red "no contrast coefficients given"
		exit 198
	}
	if "`coeffs'"!="" & "`trend'"!="" {
		di in red "cannot have both trend and coeffs"
		exit 198
	}
* --MEANS SPECIFIED-----------------------------------------------------------
	if "`means'"!="" {
		if "`trend'"!=""  {
			local opts "trend"
		}
		else {
			cap confirm var `coeffs'
			local rc=_rc
			if !`rc' { /* coeffs are in a variable */
				local opts "coeffs(`coeffs')"
			}
			else { /* parse coeffs and convert to variable */
				cap drop __coeffs
				pc "`coeffs'" __coeffs
				if $S_1!=_N { di in red /*
		 */ "number of coefficients unequal to number of means"
					exit 198
				}
				local opts "coeffs(__coeffs)"
			}
		}
		aov1cont `varlist' `if' `in', `opts' level(`level')
		cap drop __coeffs
		exit
	}

* -FULL ANOVA CASE, WITH RAW DATA---------------------------------------------

	parse "`varlist'", parse(" ")
/*
	Store y and names of grouping variable(s)
*/
	local yvar `1'
	local gvar1 `2'
	mac shift
	mac shift
	local gvar2 "`*'"
	tempvar a y g1 g1m g1s g1n touse
/*
	Set up data and count number of groups in gvar1 (ng1).
	Note change in this version: now set up group 1 indicator (g1)
	as long integer 1, 2, ... using egen.
*/
	quietly {
		mark `touse' `if' `in'
		markout `touse' `yvar' `gvar1' `gvar2'
		gen `y' = `yvar' if `touse'
		egen long `g1' = group(`gvar1') if `touse'
		drop `touse'
		sum `g1'
		local obs = _result(1)
		local ng1 = _result(6)
/*
	Calc residual SD and F test for first (or only) factor
*/
		anova `y' `g1' `gvar2', `options'
		local rdf = _result(5)
		local rsd = _result(9)
		if `rdf'==0 | `rdf'==. {
			di in red "zero residual degrees of freedom"
			exit 2001
		}
		test `g1'
		local vratio = _result(6)
		local Pgrp = fprob(_result(3), `rdf', `vratio')
/*
	Factor 1 levels: store counts and means
*/
		egen long `g1n' = count(`y'), by(`g1')
		if "`adjust'"!="" {
			tempvar tmp
			pred `tmp'
			egen `g1m' = mean(`tmp'), by(`g1')
			replace `tmp' = `y'-`tmp' /* anova residuals */
			egen `g1s' = sd(`tmp'), by(`g1')
			drop `tmp'
		}
		else  {
			egen `g1m' = mean(`y'), by(`g1')
			egen `g1s' = sd(`y'), by(`g1')
		}
/*
	Store contrast coeffs
*/
		if "`trend'"!="" {
			local nc `ng1'
			gen `a' = _n in 1/`nc'
		}
		else {
			pc "`coeffs'" `a'
			local nc $S_1
		}
/*
	Find coefficient mean
*/
		sum `a'
		local ncgood = _result(1)
		local cmean = _result(3)
/*
	Calc contrast and its SE (by literal method)
*/
		tempname big
		scalar `big' = -1e30
		cap drop __a
		gen __a = `big'
		if "`coeffs'"!="" {
			cap drop __coeffs
			gen __coeffs = `big'
			local c __coeffs
		}
		local i 1
		local L 0
		local N 0
		local varL 0
		local index 1
		while `i'<=`nc' {
			local n = `g1n'[`index']
			local ca = `a'[`i']	/* original coefficient */
			local cc = `ca'-`cmean' /* standardized coef */
			replace __a = `cc' in `index'
			if "`coeffs'"!="" {
				replace __coeffs = `ca' in `index'
			}
			if `ca'!=. {
				local L = `L'+`cc'*`g1m'[`index']
				local varL = `varL'+`cc'^2/`n'
				local N = `N'+`n'
			}
			local index = `index'+`n'
			local i = `i'+1
		}
		drop `a'
	}
	local seL = `rsd'*sqrt(`varL')
	local t = `L'/`seL'
	local invt = invt(`rdf', `level'/100) 
	local lower = `L' - `invt'*`seL'
	local upper = `L' + `invt'*`seL'
	local P = fprob(1, `rdf', `t'^2)
/*
	Output results
*/
*!!	Following code is a horrible kludge to deal with -list-'s inability
*!!	to cope with user-supplied var labels. Don't need __* to be permanent.

	cap drop __n
	cap drop __mean
	cap drop __res_sd
	rename `g1n' __n
	rename `g1m' __mean
	rename `g1s' __res_sd
	list `gvar1' __n __mean __res_sd `c' __a if __a>`big', noobs
	drop __n __mean __res_sd `c' __a

	_jprcout `yvar' `gvar1' `obs' `L' `seL' `lower' `upper' `t' `P' /*
	 */ `vratio' `Pgrp' `rdf' `rsd' `level'

	global S_1 `N'
	global S_2 `ng1'
	global S_3 `L'
	global S_4 `seL'
	global S_5 `lower'
	global S_6 `upper'
	global S_7 `t'
	global S_8 `P'
end

program define pc /* parse and store coefficients */
* 1=coefficients, 2=variable name to hold them
local coeffs "`1'"
local c `2'
parse "`coeffs'", parse(" ,")
qui gen `c' = .
local nc 0
while "`1'"!="" {
	if "`1'" == "," { mac shift }
	if "`1'"!="." { noi confirm number `1' }
	local nc = `nc'+1
	qui replace `c' = `1' in `nc'
	mac shift
}
global S_1 `nc'
end