program def ordplot
*! 1.2.1 NJC 23 Oct 2000
* 1.2.0 NJC 23 Oct 2000
* 1.1.1 NJC 18 Oct 2000
* 1.0.0 NJC 12 Oct 2000
	version 6.0
	syntax varname(numeric) [if] [in] [fweight] [ , SCale(str) /*
	*/ POWer(real 0) by(varname) sep(str) Connect(str) Keys(str) /*
	*/ L1title(str asis) L2title(str asis) ASSCores(numlist asc) /*
	*/ le lt ge gt PRob Fraction MISSing REVerse  /*
	*/ PLAbel(numlist >=0 <=100) PLIne(numlist >=0 <=100) /*
	*/ PTIck(numlist >=0 <=100) Gap(int 4) YLAbel YLAbel(numlist) /*
	*/ YTIck YTick(numlist) YLIne YLIne(numlist) * ]

	local ineq = trim("`le' `lt' `ge' `gt'")
	local nineq : word count `ineq'
	if `nineq' > 1 {
		di in r "must choose between `ineq' options"
		exit 198
	}

	if "`reverse'" != "" & "`le'`lt'" != "" {
		di in r "`le'`lt' option not allowed with reverse option"
		exit 198
	}
	else if "`reverse'" == "" & "`ge'`gt'" != "" {
		di in r "`ge'`gt' option requires reverse option"
		exit 198
	}

	if "`scale'" == "percent" & "`fraction'" != "" {
		di in r /*
		*/ "must choose between scale(percent) and fraction options"
		exit 198
	}

	if "`scale'" == "percent" { local desc "percent" }
	else if "`fraction'" != "" { local desc "fraction" }
	else local desc "probability"

	if "`scale'" != "" {
		local OK 0
		if "`scale'" == "logit" { local OK 1 }
		else if "`scale'" == "flog" { local OK 1 }
		else if "`scale'" == "froot" { local OK 1 }
		else if "`scale'" == "folded" {
			if `power' == 0 {
				di in r "need power( ) with folded scale"
				exit 198
			}
			local OK 1
		}
		else if "`scale'" == "loglog" { local OK 1 }
		else if "`scale'" == "cloglog" { local OK 1 }
		else if "`scale'" == "normal" { local OK 1 }
		else if "`scale'" == "gaussian" {
			local scale "Gaussian"
			local OK 1
		}
		else if "`scale'" == "Gaussian" { local OK 1 }
		else if "`scale'" == "percent" { local OK 1 }
		else if "`scale'" == "raw" { local OK 1 }
		if !`OK' {
			di in r "invalid scale( ) option"
			exit 198
		}
	}
	else local scale "raw"

	if "`plabel'" != "" {
		if "`ylabel'" != "" {
			di in r /*
			*/ "must choose between plabel and ylabel options"
			exit 198
		}
		if "`scale'" == "raw" | "`scale'" == "percent" {
			di in r /*
			*/ "use ylabel( ) not plabel( ) with scale(`scale')"
			exit 198
		}
		local npla : word count `plabel'
		local pmax : word `npla' of `plabel'
		if `pmax' > 1 { local desc "percent" }
	}

	if "`pline'" != "" {
		if "`yline'" != "" {
			di in r /*
			*/ "must choose between pline and yline options"
			exit 198
		}
		if "`scale'" == "raw" | "`scale'" == "percent" {
			di in r /*
			*/ "use yline( ) not pline( ) with scale(`scale')"
			exit 198
		}
		local npli : word count `pline'
		local pmax : word `npli' of `pline'
		if `pmax' > 1 { local desc "percent" }
	}

	if "`ptick'" != "" {
		if "`ytick'" != "" {
			di in r /*
			*/ "must choose between ptick and ytick options"
			exit 198
		}
		if "`scale'" == "raw" | "`scale'" == "percent" {
			di in r /*
			*/ "use ytick( ) not ptick( ) with scale(`scale')"
			exit 198
		}
		local npti : word count `ptick'
		local pmax : word `npti' of `ptick'
		if `pmax' > 1 { local desc "percent" }
	}

	local y "`varlist'"

	if "`by'" == "" {
		local onevar 1
		tempvar x
		gen byte `x' = 1
	}
	else {
		local onevar 0
		capture confirm numeric variable `by'
		if _rc {
			tempvar x
			encode `by', gen(`x')
		}
		else local x "`by'"
	}

	marksample touse
	if "`missing'" == "" & !`onevar' {
		markout `touse' `x'
	}

	if !`onevar' {
		qui tab `x' if `touse', `missing'
		if `r(r)' > 10 {
			di in r "`x' has too many categories to plot"
			exit 198
		}
	}

	if "`asscores'" != "" {
		local nsc : word count `asscores'
		tempname yval ylbl
		qui tab `y' if `touse', matrow(`yval')
		local nvals = `r(r)'
		if `nsc' != `nvals' {
			di in r /*
		*/ "`nsc' values in asscores( ), `nvals' values of `y'"
			exit 198
		}
	}

	preserve

	if "`asscores'" != "" {
		tempvar scores
		qui gen `scores' = .
		local vallbl : value label `y'
		local i = 1
		qui while `i' <= `nvals' {
			local as : word `i' of `asscores'
			local val = `yval'[`i',1]
			replace `scores' = `as' if `y' == `val'
			if "`vallbl'" != "" {
				local val : label `vallbl' `val'
			}
			capture label def `ylbl' `as' "`val'", modify
			local i = `i' + 1
		}
		capture label val `scores' `ylbl'
		_crcslbl `scores' `y'
		local y "`scores'"
	}

	contract `x' `y' if `touse' [`weight' `exp'], zero

	tempvar total pr show
	qui by `x' : gen `total' = sum(_freq)
	qui by `x' : replace `total' = `total'[_N]
	gen `pr' = _freq / `total'

	qui if "`prob'" == "" {
		if "`le'`gt'" != "" { /* <= or > */
			by `x' : gen `show' = sum(`pr')
		}
		else if "`lt'`ge'" != "" { /* < or >= */
			by `x' : gen `show' = sum(`pr'[_n-1])
		}
		else by `x' : gen `show' = 0.5 * `pr' + sum(`pr'[_n-1])
		if "`reverse'" != "" { replace `show' = 1 - `show' }
		local cumul "cumulative "
	}
	else local show "`pr'"

	if "`scale'" == "logit" | "`scale'" == "flog" {
		qui replace `show' = log(`show' / (1 - `show'))
	}
	else if "`scale'" == "froot" {
		qui replace `show' = sqrt(`show') - sqrt(1 - `show')
	}
	else if "`scale'" == "folded" {
		qui replace `show' = `show'^`power' - (1 - `show')^`power'
		local Power " ^`power'"
	}
	else if "`scale'" == "loglog" {
		qui replace `show' = -log(-log(`show'))
	}
	else if "`scale'" == "cloglog" {
		qui replace `show' = log(-log(1 - `show'))
	}
	else if "`scale'" == "normal" | "`scale'" == "Gaussian" {
		qui replace `show' = invnorm(`show')
	}
	else if "`scale'" == "percent" {
		qui replace `show' = 100 * `show'
	}

	if "`sep'" == "" { local sep "\" }

	if "`plabel'`pline'`ptick'" != "" {
		qui replace `show' = 1000 * `show'
	}

	if `onevar' {
		local vallist " "
	}
	else {
		tempname xval
		local vallbl : value label `x'
		qui tab `x', matrow(`xval') `missing'
		local nvals = r(r)
		local Sep "`sep'"
		local i = 1
		while `i' <= `nvals' {
			local val = `xval'[`i',1]
			if "`vallbl'" != "" {
				local val : label `vallbl' `val'
			}
			if `i' == `nvals' { local Sep }
			local vallist "`vallist' `val'`Sep'"
			local i = `i' + 1
		}
		qui separate `show', by(`x') g(_ord) `missing'
		local show "`r(varlist)'"
	}

	if "`plabel'" != "" {
		tempname tplabel
		tokenize `plabel'
		while "`1'" != "" {
			local one `1'
			t_to_p `1' tpla `desc' `scale' `power'
			if `tpla' < . {
				label def `tplabel' `tpla' "`one'", modify
				local tla "`tla' `tpla'"
			}
			mac shift
		}
		local show1 : word 1 of `show'
		label val `show1' `tplabel'
		local yla "yla(`tla')"
	}
        else if "`ylabel'" == "" | "`ylabel'" == "ylabel" {
		local yla "yla"
	}
	else if "`ylabel'" != "" {
		local yla "yla(`ylabel')"
	}

	if "`pline'" != "" {
		tokenize `pline'
		while "`1'" != "" {
			t_to_p `1' tpli `desc' `scale' `power'
			if `tpli' < . {
				local tli "`tli' `tpli'"
			}
			mac shift
		}
		local yli "yli(`tli')"
	}
	else if "`yline'" == "yline" {
		local yli "yli"
	}
	else if "`yline'" != "" {
		local yli "yli(`yline')"
	}

	if "`ptick'" != "" {
		tokenize `ptick'
		while "`1'" != "" {
			t_to_p `1' tpti `desc' `scale' `power'
			if `tpti' < . {
				local tti "`tti' `tpti'"
			}
			mac shift
		}
		local yti "yti(`tti')"
	}
	else if "`ytick'"  == "ytick" {
		local yti "yti"
	}
	else if "`ytick'" != "" {
		local yti "yti(`ytick')"
	}

	if "`connect'" == "" {
		local ny : word count `show'
		local connect : di _dup(`ny') "L"
	}
	if `"`l1title'"' == "" {
		if "`scale'" != "raw" & "`scale'" != "percent" {
			local Scale ", `scale' scale `Power'"
		}
		local l1title "`cumul'`desc'`Scale'"
	}
	if `"`l2title'"' == "" {
		if "`prob'" == "" {
			if "`le'" != "" {
				local l2title "(<= `y')"
			}
			else if "`lt'" != "" {
				local l2title "(< `y')"
			}
			else if "`ge'" != "" {
				local l2title "(>= `y')"
			}
			else if "`gt'" != "" {
				local l2title "(> `y')"
			}
			else local l2title "(to mid-class)"
		}
		else local l2title `"" ""'
	}
	if "`keys'" == "" {
		local keys "`vallist'"
	}

	keyplot `show' `y', l1(`l1title') l2(`l2title') gap(`gap')  /*
 	*/ c(`connect') keys(`keys') sep(`sep') `options' `yla' `yli' `yti'
end

program def t_to_p
* converts transformed value t to result given desc scale [power]
	version 6.0
	args t p desc scale power

	if "`desc'" == "percent" { local t = `t' / 100 }

	if "`scale'" == "logit" | "`scale'" == "flog" {
		local P = round(1000 * log(`t' / (1 - `t')),1)
	}
	else if "`scale'" == "froot" {
		local P = round(1000 * (sqrt(`t') - sqrt(1 - `t')),1)
	}
	else if "`scale'" == "folded" {
		local P = round(1000 * (`t'^`power' - (1 - `t')^`power'),1)
	}
	else if "`scale'" == "loglog" {
		local P = round(1000 * -log(-log(`t')),1)
	}
	else if "`scale'" == "cloglog" {
		local P = round(1000 * log(-log(1 - `t')),1)
	}
	else if "`scale'" == "normal" | "`scale'" == "Gaussian" {
		local P = round(1000 * invnorm(`t'),1)
	}

	c_local `p' = `P'
end