*! dsum v1.2.0 jnighohossian 25jun2013
*! This program provides a quick summary of variables in a dataset
*! version one provides total observations, missing, and distinct values
*! v1.1.0 adds dynamic column placing and counts
*! v1.2.0 adds if/in capability

program dsum
version 12.1
syntax varlist [if] [in] [, sum]

tempvar isdistinct touse

mark `touse' `if' `in'

qui count if `touse'
local obs=r(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 col4t=`col3t'+15
local col2=`col1'+15
local col3=`col2'+14
local col4=`col3'+7


n display as txt _col(`col1t') "missing" _col(`col2t') "% missing" _col(`col3t') "distinct" _col(`col4t') "`sum'"


foreach var of varlist `varlist' {
	local distinct=""
	local sum=""
	local missing=""
	local missing_pct=""
	qui {
		if substr("`:type `var''",1,3)=="str" {
			count if `var'=="" & `touse'
			local missing=`r(N)'
			local missing_pct=`missing'/`obs'*100
			bysort `var': gen byte `isdistinct'=(_n==1) & `var'!=""
			sum `isdistinct' if `touse'
			local distinct=`r(sum)'
		}
		else {
			sum `var' if `touse'
			if "`sum'"=="sum" local sum1 `r(sum)'
			inspect `var' if `touse'
			local missing=(`obs'-`r(N)')
			local missing_pct=`missing'/`obs'*100
			bysort `var': gen byte `isdistinct'=(_n==1) & `var'!=.
			sum `isdistinct' if `touse'
			local distinct=`r(sum)'
		}
	}
	n	display as txt "`var'"  _col(`col1') as res %9.0f `missing' _col(`col2')  %6.2f `missing_pct' _col(`col3') %3.0f "`distinct'" _col(`col4') %9.2gc "`sum1'"
	drop `isdistinct'
}

end