*! version 1.2 07nov2016
program define checkvar, rclass
syntax varlist [if] [in]
version 8
// program drops most obs and vars for efficiency,
// so first preserve the original data
preserve
if "`if'" != "" {
keep `if'
}
if "`in'" != "" {
keep `in'
}
keep `varlist'
// replace string missing with "." for better display
local all_numeric 1
foreach v of varlist `varlist' {
loc type : type `v'
if substr("`type'",1,3) == "str" {
quietly replace `v' = "." if `v' == ""
local all_numeric 0
}
}
// separate first variable in varlist as "created variable"
// and remainder as "component variables"
tokenize `varlist'
local createdvar `1'
macro shift
local componentvars `*'
// Thanks to Dan Blanchette for this algorithm,
// and to Nick Cox for the following 3 lines -
// much more efficient than the way I was doing it.
tempvar freq
bysort `varlist': gen `freq' = _N
quietly by `varlist': keep if _n == 1
// sort by created var, then components within it,
// and display as a table
di _newline
// title line
di _col(3) as text "Created Variable: " ///
as result "`createdvar'"
// column header line
local b = " "
local c = "14"
local countvars = "0"
foreach v of varlist `componentvars' {
local col = "_col(`c')"
local y = abbrev("`createdvar'",8)
local x = abbrev("`v'",8)
local varnames `"`varnames' `b' `col' `b' %8s "`x'" `b'"'
local c = `c' + 10
local countvars = `countvars' + 1
}
local c = `c' - 1
local col = "_col(`c')"
local hlinelength = (`countvars' * 10)
di as text _col(3) "{hline 9}{c TT}{hline `hlinelength'}{c TT}{hline 9}"
di as text _col(3) %8s "`y'" ///
_col(12) "{c |}" `varnames' ///
`col' "{c |}" %9s "Freq"
di as text _col(3) "{hline 9}{c +}{hline `hlinelength'}{c +}{hline 9}"
// display each combination of created variable with its
// unique sets of component vars as separate lines in a table
// first build a display list of the component-variable combinations
// (each obs is a unique combination for that value of created var)
forval i = 1/`=_N' {
local c = "14"
foreach v of varlist `componentvars' {
local col = "_col(`c')"
local x = "`v'[`i']"
loc type : type `v'
// display string values with %8s format, trim leading & trailing blanks,
// and truncate string values to first 8 characters
// so they don't push over the next column
if substr("`type'",1,3) == "str" {
local displaylist "`displaylist' `b' `col' `b' %8s `x'"
quietly replace `v' = substr(trim(`v'),1,8) in `i'
}
// display numeric values with %8.0g format
else {
local displaylist "`displaylist' `b' `col' `b' %8.0g `x'"
}
local c = `c' + 10
}
// put the created-variable value on the front, and the freq on the end
local c = `c' - 1
local col = "_col(`c')"
local y = "`createdvar'[`i']"
di _col(3) as result %8.0g `y' ///
_col(12) as text "{c |}" ///
as result `displaylist' ///
`col' as text "{c |}" ///
as result %9.0g `freq'[`i']
local displaylist ""
// put a dividing line between each new value of the created var
if `createdvar'[`i'] ~= `createdvar'[`i'+1] & `i'<_N {
di as text _col(3) "{hline 9}{c +}{hline `hlinelength'}{c +}{hline 9}"
}
}
di as text _col(3) "{hline 9}{c BT}{hline `hlinelength'}{c BT}{hline 9}"
// create a matrix if all numeric variables
if `all_numeric' {
mkmat `varlist' `freq', mat(checkvar)
matrix colnames checkvar = `varlist' freq
return matrix checkvar checkvar
}
return local combos `=_N'
end
exit
HISTORY
07nov2016 - fixed an error that prevented "if" and "in" from working
11mar2009 - updated help and sent to Kit for inclusion in SSC archive
29dec2008 - added "if" and "in" options
15jun2004 - shows all unique combinations of the component vars when they are listed
in the varlist without the created var - this is more than the command is
intended to do, but people tried to use it this way (a la -groups-)
and found that it dropped one or more combinations of the component vars.
saves number of combinations in r(combos), and matrix of combinations
and their frequencies in r(checkvar), if varlist is numeric.
09dec2003 - made 3 changes suggested by Nick Cox, one a correction, one an efficiency
enhancement, and one replacing -while- with -forval-
11aug2003 - fixed the problem where displaylist was a string variable and couldn't
grow past 244 characters
06Jun2003 - no error checks except built-in (can't think of any more to do)
abbreviate varnames to 8 characters
change string blank to "." so it displays more clearly in table
display using formats so all labels and values are right justified in column
truncate string values to first 8 characters so they don't push next column