*! version 1.1   30Nov2021 by Mead Over.  Hacked to return results, add reldif option
*! based on version version 2.2.8  17dec2020 of Stata's -compare.ado-
program compare2, byable(recall) rclass
	version 7, missing
	syntax varlist(min=2 max=2) [if] [in], [Reldif Width(integer 80)]
	tokenize `varlist'
	tempvar touse
	mark `touse' `if' `in'
	/* we do not markout the missing values */

	local extrawidth = (`width' - 72)
	if `extrawidth' < 0 {
		di as err "Option width(integer) accommodates integers >= 72"
		exit 198
	}
	foreach cno of numlist 10 24 25 29 33 39 41 52 54 64 66 72 {
		local c`cno' = `cno' + `extrawidth'
	}

	tempvar MISS1 MISS2 DIFF
	local nd "noisily di"
	quietly {
		local type1 : type `1'
		local type2 : type `2'
		if (bsubstr(`"`type1'"',1,3)=="str") {
			gen byte `MISS1' = `1'=="" if `touse'
			local type1 "s"
		}
		else {
			gen byte `MISS1' = `1'>=. if `touse'
			local type1 "n"
		}
		if (bsubstr(`"`type2'"',1,3)=="str") {
			gen byte `MISS2' = `2'=="" if `touse'
			local type2 "s"
		}
		else {
			gen byte `MISS2' = `2'>=. if `touse'
			local type2 "n"
		}

		local vn1 = abbrev("`1'",9 + floor(`extrawidth'/2))
		local vn2 = abbrev("`2'",9 + floor(`extrawidth'/2))

		if `"`type1'"'=="s" | `"`type2'"'=="s" {
			`nd' in smcl _n in gr _col(`c29') "count" _n "{hline `c33'}"
		}
		else {
			local dodif "y"
			`nd' in smcl _n in gr /*
			*/ _col(`c41') "{hline 10} Difference {hline 10}" _n /*
			*/ _col(`c29') "Count" _col(`c41') "Minimum" /*
			*/ _col(`c54') "Average" /*
			*/ _col(`c66') "Maximum" _n /*
			*/ "{hline `c72'}"
		}
		count if `MISS1'==0 & `MISS2'==0
			local joint = r(N)
		if `joint'==0 & `"`type1'"'==`"`type2'"' {
			local jnt1lt2 0
			local jnteq 0
			local jnt1gt2 0
		}
		if `joint' & `"`type1'"'==`"`type2'"' {
			if `"`dodif'"'=="y" {
				gen float `DIFF' = `1'-`2' if `MISS1'==0 /*
				*/ & `MISS2'==0
				count if missing(`DIFF') & `MISS1'==0 ///
								& `MISS2'==0
				if (r(N)>0) {
					tempvar DIFF2
					gen double `DIFF2' = `1' - `2'	///
						if missing(`DIFF')	///
						   & `MISS1'==0 & `MISS2'==0
					replace `DIFF2'=`DIFF'		///
						 if !missing(`DIFF')
					drop `DIFF'
					rename `DIFF2' `DIFF'
				}
			}
			count if `1'<`2' & `MISS1'==0 & `MISS2'==0
				local jnt1lt2 `r(N)'
			if r(N) {
				local c = r(N)
				if `"`dodif'"'=="y" {
					sum `DIFF' if `DIFF'<0 & `DIFF'<., /*
						*/ meanonly
					`nd' in gr "`vn1'<`vn2'" _col(`c25') /*
					*/ in ye %9.0f `c' _col(`c39') /*
					*/ %9.0g r(min) _col(`c52') /*
					*/ %9.0g r(mean) _col(`c64') /*
					*/ %9.0g r(max)
					local min1lt2 `r(min)'
					local mn1lt2  `r(mean)'
					local max1lt2 `r(max)'
				}
				else {
					`nd' in gr `"`vn1'<`vn2'"' _col(`c25') /*
					*/ in ye %9.0f `c'
				}
			}
			count if `1'==`2' & `MISS1'==0 & `MISS2'==0
				local jnteq  `r(N)'
			if r(N) {
				`nd' in gr `"`vn1'=`vn2'"' _col(`c25') in ye /*
				*/ %9.0f r(N)
			}
			count if `1'>`2' & `MISS1'==0 & `MISS2'==0
				local jnt1gt2 `r(N)'
			if r(N) {
				local c = r(N)
				if `"`dodif'"'=="y" {
					sum `DIFF' if `DIFF'>0 & `DIFF'<., /*
						*/ meanonly
					`nd' in gr `"`vn1'>`vn2'"' _col(`c25') /*
					*/ in ye %9.0f `c' _col(`c39') /*
					*/ %9.0g r(min) _col(`c52') /*
					*/ %9.0g r(mean) _col(`c64') /*
					*/ %9.0g r(max)
					local min1gt2 `r(min)'
					local mn1gt2  `r(mean)'
					local max1gt2 `r(max)'
				}
				else {
					`nd' in gr `"`vn1'>`vn2'"' _col(`c25') /*
					*/ in ye %9.0f `c'
				}
			}
			`nd' in smcl in gr _col(`c24') "{hline 10}"
		}		/* end of joint detail	*/
		if `joint' {
			if `"`dodif'"'=="y" {
				sum `DIFF', meanonly
				`nd' in gr "Jointly defined" _col(`c25') /*
				*/ in ye %9.0f `joint' _col(`c39') /*
				*/ %9.0g r(min) _col(`c52') /*
				*/ %9.0g r(mean) _col(`c64') /*
				*/ %9.0g r(max)
				local minjnt `r(min)'
				local mnjnt  `r(mean)'
				local maxjnt `r(max)'
			}
			else {
				`nd' in gr "Jointly defined" _col(`c25') /*
				*/ in ye %9.0f `joint'
			}
		}
		count if `MISS1'==1 & `MISS2'==0
			local v1msng `r(N)'
		if r(N) {
			if "`vn1'"=="" {
				`nd' in gr `"Missing only"' _col(`c25') /*
				*/ in ye %9.0f r(N)
			}
			else {
				`nd' in gr `"`vn1' missing only"' _col(`c25') /*
				*/ in ye %9.0f r(N)
			}
		}
		count if `MISS1'==0 & `MISS2'==1
			local v2msng `r(N)'
		if r(N) {
			if "`vn2'"=="" {
				`nd' in gr `"Missing only"' _col(`c25') /*
				*/ in ye %9.0f r(N)
			}
			else {
				`nd' in gr `"`vn2' missing only"' _col(`c25') /*
				*/ in ye %9.0f r(N)
			}
		}
		count if `MISS1'==1 & `MISS2'==1
			local bthmsng `r(N)'
		if r(N) {
			`nd' in gr "Jointly missing" _col(`c25') /*
			*/ in ye %9.0f r(N)
		}
		`nd' in smcl in gr _col(`c24') "{hline 10}"
		count if `MISS1'<. & `MISS2'<.
		`nd' in gr "Total" _col(`c25') in ye %9.0f r(N)
			local total `r(N)'

	}

	if "`reldif'"~="" {
		if "`type1'"=="n" & "`type2'"=="n" {
			return clear
			tempvar rd
			qui gen double `rd' = reldif(`1',`2')  if `touse'
				char def `rd'[varname] reldif
			di _n as txt "Summary statistics of the relative difference between " as res "`1'" as txt " and " as res "`2'" as txt ","  ///
				_n "defined as reldif( " as res "`1'" as txt " , " as res "`2'" as txt " ).  See " in smcl "{stata help reldif}"
			sum `rd'  if `touse'
			return add
		}
		else {
			di as err "The option -reldif- requires that both variables being compared are numeric."
			error 109
		}
	}

*	Results saved by -compare2-, not by -compare-
*	To avoid increasing the version number from "version 6",
*	restrict the length of the names of local macros.
	return local total    `total'
	return local bthmsng  `bthmsng'
	return local v2msng   `v2msng'
	return local v1msng   `v1msng'
	return local maxjnt   `maxjnt'
	return local mnjnt    `mnjnt'
	return local minjnt   `minjnt'
	return local joint    `joint'
	return local max1gt2  `max1gt2'
	return local mn1gt2   `mn1gt2'
	return local min1gt2  `min1gt2'
	return local jnt1gt2  `jnt1gt2'
	return local jnteq    `jnteq'
	return local max1lt2  `max1lt2'
	return local mn1lt2   `mn1lt2'
	return local min1lt2  `min1lt2'
	return local jnt1lt2  `jnt1lt2'

end

* version 1.0.0 20may2017 by Mead Over.  Like Stata's -compare.ado-, but also returns results
* version 1.0.1 1jun2017  cleaned out extra debug output.
* version 1.0.2 1Jan2020  Add the -reldif- option.
* version 1.1   30Nov2021 Add the option width, with default value of 80.