*! 2.0.3 RP 30may2017 * 2.0.2 RP 23jun2016 * 2.0.1 RP 15sep2015 * 2.0.0 RP 10sep2015 * 1.0.6 RP 24aug2015 * 1.0.5 RP 08aug2015 * 1.0.4 RP 22jul2015 * 1.0.3 RP 08jul2015 * 1.0.2 NJC 02jul2015 * version 1.0.1, 02jul2015, Robert Picard, picard@netbox.com program dataex version 9.2 syntax [varlist] [if] [in] [, Varlabels Elsewhere Count(string)] if "`count'" == "" local maxobs 100 else { if "`count'" != "." confirm number `count' local maxobs `count' } if "`varlist'" == "" { dis as err "no variables in memory; nothing to generate" exit 111 } local varlist : list uniq varlist local raw_obs = _N preserve if `"`if'`in'"' != "" qui keep `if' `in' if _N == 0 { dis as err "no observations; nothing to generate" exit 2000 } keep `varlist' local Ntouse = _N if `Ntouse' > `maxobs' qui keep in 1/`maxobs' // set linesize to the maximum allowed under all Stata versions up to 14. // this should be 255 but strings of that length cannot be copied local lssave = c(linesize) local maxwidth 254 set linesize `maxwidth' // group variables by type; respect current variable order local i 0 foreach v of varlist `varlist' { local vtype : type `v' if "`vtype'" != "`vtypeold'" { local ++i local vtype`i' `vtype' local vlist`i' `v' local vtypeold `vtype' } else { local vlist`i' `vlist`i'' `v' } } // build the input statement local input input forvalues j = 1/`i' { local n : word count `vlist`j'' if `n' == 1 { local input `input' `vtype`j'' `vlist`j'' } else { local input `input' `vtype`j''(`vlist`j'') } } if `: length local input' > `maxwidth' { dis as err "input statement exceeds linesize limit. Try specifying fewer variables" set linesize `lssave' exit 1000 } dis as txt _n "{hline 23} copy starting from the next line {hline 23}" if "`elsewhere'" == "" dis as res "[CODE]" dis as res "* Example generated by -dataex-. To install: ssc install dataex" dis as res "clear" dis as res "`input'" // cycle through variables and build output lines using a string variable local spaces : dis _dup(`maxwidth') " " tempvar line_out sv sv_len x xtend xdif qui gen `line_out' = "" local line_out_len 0 foreach v of varlist `varlist' { local vtype : type `v' if strpos("`vtype'","str") == 1 { qui gen `sv' = cond(strpos(`v',char(34)), /// "`" + `"""' + `v' + `"""' + "'", `"""' + `v' + `"""') } else if inlist("`vtype'", "byte", "int", "long") { qui gen `sv' = string(`v',"%11.0f") } else { // initially, write floats and doubles using default display format local w = cond("`vtype'" == "double", 10, 9) qui gen `sv' = string(`v', "%`w'.0g") // widen format until the string representation can be converted // back to within an epsilon of the original number (in proportion) local wmax = cond("`vtype'" == "double", 25, 16) local epsilon = cond("`vtype'" == "double", 1e-16, 1e-7) local more 1 qui while `more' { gen `vtype' `x' = real(`sv') gen double `xdif' = abs((`v' - `x') / `v') gen byte `xtend' = `xdif' > `epsilon' & `v' != 0 & !mi(`v') replace `xtend' = 1 if mi(`x') & !mi(`v') // if near min/max // there's a bug in the %g format that can generate a number // that can be off by a factor of 10; switch to %e format when needed sum `xdif' if `xtend', meanonly local eg = cond(r(max) > .1, "e", "g") count if `xtend' if r(N) replace `sv' = string(`v',"%`++w'.0`eg'") if `xtend' if r(N) == 0 | `w' == `wmax' local more 0 drop `xtend' `x' `xdif' } } // pad all values to align columns; left-align strings, right-align everything else gen `sv_len' = length(`sv') sum `sv_len', meanonly if strpos("`vtype'","str") == 1 { qui replace `sv' = `sv' + substr("`spaces'", 1, r(max) - `sv_len') } else { qui replace `sv' = substr("`spaces'", 1, r(max) - `sv_len') + `sv' } local line_out_len = `line_out_len' + length("`space1'") + r(max) if c(stata_version) < 13 { if `line_out_len' > c(maxstrvarlen) { dis as err "data width (`line_out_len' chars) exceeds max string length. Try specifying fewer variables" set linesize `lssave' exit 1000 } } else if `line_out_len' > `maxwidth' { dis as err "data width (`line_out_len' chars) exceeds max linesize. Try specifying fewer variables" set linesize `lssave' exit 1000 } qui replace `line_out' = `line_out' + "`space1'" + `sv' local space1 " " drop `sv' `sv_len' } // allow user to break out of the list output cap noi forvalues i = 1/`=_N' { local nout = `i' dis as res `line_out'[`i'] } // continue if the break key (return code 1) was used to stop the output local break_obs 0 if _rc == 1 { local break_obs 1 } else if _rc > 1 exit _rc dis as res "end" // so that labels can be based on what was printed in case of a break if `nout' < _N qui keep in 1/`nout' cap noi { // format numeric variable if it's a SIF (datetime) foreach v of varlist `varlist' { local f : format `v' if regexm(`"`f'"', "^%-?(t|d)") dis as res `"format `f' `v'"' } // make a list of values label names assigned to variables local vlabels foreach v of varlist `varlist' { local l : value label `v' if "`l'" != "" local vlabels : list vlabels | l } // define value labels once for all variables that use them foreach vl in `vlabels' { local alllevels qui ds , has(vallabel `vl') local vlist `r(varlist)' foreach v of varlist `vlist' { qui levelsof `v', local(levels) missing local alllevels : list alllevels | levels dis as res "label values `v' `vl'" } foreach n in `alllevels' { local ltext : label `vl' `n', strict if `"`ltext'"' != "" { if strpos(`"`ltext'"',char(34)) dis as res `"label def `vl' `n' `"`ltext'"', modify"' else dis as res `"label def `vl' `n' "`ltext'", modify"' } } } // variable labels if "`varlabels'" != "" { foreach v of varlist `varlist' { local ltext : var label `v' if `"`ltext'"' != "" { if strpos(`"`ltext'"',char(34)) dis as res `"label var `v' `"`ltext'"' "' else dis as res `"label var `v' "`ltext'" "' } } } } local break_post 0 if _rc == 1 { local break_post 1 } else if _rc > 1 exit _rc if "`elsewhere'" == "" dis as res "[/CODE]" dis as txt "{hline 18} copy up to and including the previous line {hline 18}" dis as txt dis as txt "Listed " as res `nout' as txt " out of " as res `raw_obs' as txt " observations" if `break_obs' dis as err "Listing of observations interrupted due to user -break-" else if "`count'" == "" & `nout' < `Ntouse' dis as txt "Use the count() option to list more" if `break_post' { dis as err "Some important information about formats and value labels is missing due to user -break-" } set linesize `lssave' end