*! varcheck v1.0.0 jnighohossian 10feb2014
*! This program provides a quick summary of variables in a dataset
*! Especially useful for longitudinal data to check variables over wave

program varcheck
version 12.1
syntax varlist[, by(varname)]

qui {
	local by_bool="`by'"!=""
	local vnumber: list sizeof varlist
	if !`by_bool' {
		tempvar by
		g `by'=1
	}
	local valnumber=1
	levelsof `by', local(vallist)
	local valnumber: list sizeof vallist
	mat A=J(`vnumber',`valnumber',0)

	*Determine number of observations for each unique value in bylist
	mat B=J(1,`valnumber',c(N))
	local j=1
	foreach val in `vallist' {
		count if `by'==`val'
		mat B[1,`j']=r(N)
		local j=`j'+1
	}

	local obs=c(N)

	//n display as txt "Total Observations: " as res "`obs'" _newline

	local lngth0=0
	foreach var of varlist `varlist' {
		local lngth: length local var
		if `lngth'>`lngth0' {
			local lngth0=`lngth'
		}
	}

	*Determine how to format the output table (calculate column numbers)
	local col1=20
	local col1t=22
	if `lngth0'>18 {
		local col1=`lngth0'+2
		local col1t=`lngth0'+4
	}
	local col2t=`col1t'+10
	local col3t=`col2t'+11
	local col2=`col1'+15
	local col3=`col2'+14

	local i=1

	foreach var of varlist `varlist' {
		local j=1
		if substr("`:type `var''",1,3)=="str" {
			foreach val in `vallist' {
				count if `var'=="" & `by'==`val'
				local missing=`r(N)'
				local missing_pct=`missing'/`obs'*100
				mat A[`i',`j']=round(`missing',1)
				local j=`j'+1
			}
		}
		else {
			foreach val in `vallist' {
				inspect `var' if `by'==`val'
				local missing=(B[1,`j']-`r(N)')
				local missing_pct=`missing'/`obs'*100
				mat A[`i',`j']=round(`missing',1)
				local j=`j'+1
			}
		}
		local i=`i'+1
	}

	mata: st_matrix("C",st_matrix("A"):/st_matrix("B")*100)
	matrix rownames C=`varlist'
	matrix colnames C=`vallist'
	matrix coleq C=`by'
}

mat list C, format("%4.1f") title("% missing observations")
end