*! version 1.9 Writes codebook to html file - 23Jun2010
program define cb2html, nclass
version 10
syntax [varlist] using/ [, replace TItle(str) PPrecision(integer 0) ///
Fprecision(integer 0) SPrecision(integer 0) Upper Vallabel ///
Maxvalues(integer 10) Notes TYpe COmbine(varlist min=2 max=2) ///
PAgebreak(integer 0) STringmax(integer 0) SUmmarize(integer 0)]
preserve
// Check name of "using" file and remove .html suffix and all quotes.
// Thanks to Kit Baum and Nick Cox for many ideas used in this program,
// especially for this suffix-checking section.
local using : subinstr local using ".html" ""
local using : subinstr local using ".htm" ""
local using : subinstr local using ".HTML" ""
local using : subinstr local using ".HTM" ""
local using : subinstr local using `"""' "", all /* '"' (for fooling emacs) */
local using : subinstr local using "`" "", all
local using : subinstr local using "'" "", all
// If the "using" file exists, and the "replace" option isn't specified,
// stop the program and tell the user to specify "replace".
local usingflag = 0
capture confirm file "`using'.html"
if _rc==0 {
local usingflag = 1
}
if `usingflag' == 1 & "`replace'" ~= "replace" {
di as error "The using file `using'.html already exists."
di as text "If you want to write over it, use the 'replace' option."
restore
exit
}
if `fprecision' < 0 | `fprecision' > 22 {
di as error "The value of fprecision must be an integer in the range 0 - 22."
restore
exit
}
if `sprecision' < 0 | `sprecision' > 22 {
di as error "The value of sprecision must be an integer in the range 0 - 22."
restore
exit
}
// Create a temporary file to write the html into.
tempname ho
tempfile tempho
local outfile "`tempho'"
file open `ho' using `"`outfile'"',w
// Write the html header info including the title. Use the user-supplied
// title if supplied, otherwise use the data label.
file write `ho' `""' _n
file write `ho' "" _n "
" _n
if `"`title'"' ~= "" {
file write `ho' `"`title'"' _n
}
else {
local datalab : data label
if `"`datalab'"' ~= "" {
file write `ho' `"`datalab'"' _n
}
}
file write `ho' `""' _n
file write `ho' `""' _n
file write `ho' `"" _n
file write `ho' "" _n
// *** Start the html body ***
file write `ho' "" _n
// HEADER: print the data label and first data note
// First print the data label, if one exists.
// It should be used to identify the survey name and year.
local datalab : data label
if `"`datalab'"' ~= "" {
file write `ho' `""' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " """`"`datalab'"'"" _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
}
else if `"`title'"' ~= "" {
file write `ho' `""' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " """`"`title'"'"" _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
}
// Make a label addition for "maxvalues" variables, which can be
// concatenated to note1 and variable label as needed.
local maxlabel = "NOTE: Smallest 5 and largest 5 values are displayed."
// Make a label addition for strtype == "str" variables, which can be
// concatenated to variable label when summary statistics are requested.
local strlabel = "NOTE: Cannot create summary statistics for a string variable"
// Check if there is a data note1 and "notes" is turned on.
// If so, assume note1 is something the owner wants to print,
// such as a section heading (Add Health format).
local datanote : char _dta[note1]
if `"`datanote'"' ~= "" & "`notes'" ~= "" {
file write `ho' `""' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " "`"`datanote'"' _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
}
qui des, short
local numobs = r(N)
file write `ho' `""' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " "`"Number of observations: "' %20.0gc (`numobs') _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
// If "combine" is on, get names of variables to be combined.
if "`combine'" ~= "" {
local combsep1 = strpos("`combine'"," ") - 1
local combsep2 = `combsep1' + 2
local comblength = length("`combine'")
local comb1 = substr("`combine'",1,`combsep1')
local comb2 = substr("`combine'",`combsep2',`comblength')
}
local combflag = 0
// Macros for user feedback.
local totalvar : word count `varlist'
local countvar = 0
local quarter = 0
local half = 0
local threeqtr = 0
di as text "`totalvar' variables will be written to the codebook."
di as text "Writing the html file..."
// Initialize count variable for number of lines per page,
// and start a new page for the first variable.
local lines = 0
file write `ho' "
" _n
if `pagebreak' ~= 0 {
file write `ho' `""' _n
}
local firstvar = 1
// ************************************************
// ***** Loop over each variable in `varlist' *****
// ************************************************
foreach v of varlist `varlist' {
local newlines = 0
local vartype : type `v'
local strtype = substr("`vartype'",1,3)
// Give user some feedback on progress
di as text " `v' "
local countvar = `countvar' + 1
local pctvar = `countvar'/`totalvar'
if `pctvar' > 0.25 & `quarter' == 0 {
local quarter = 1
di as text " "
di as text "25% of file written..."
di as text " "
}
if `pctvar' > 0.5 & `half' == 0 {
local half = 1
di as text " "
di as text "50% of file written..."
di as text " "
}
if `pctvar' > 0.75 & `threeqtr' == 0 {
local threeqtr = 1
di as text " "
di as text "75% of file written..."
di as text " "
}
// If "combine" is on, and "v" is the first combine variable,
// combine the variables named and substitute "combined" for "v".
// Don't print either of those vars, only print the combined variable.
if "`combine'" ~= "" & (("`v'" == "`comb1'") | ("`v'" == "`comb2'")) {
local vartype1 : type `comb1'
local vartype2 : type `comb2'
local strtype1 = substr("`vartype1'",1,3)
local strtype2 = substr("`vartype2'",1,3)
if "`strtype1'" == "str" & "`strtype2'" == "str" {
gen str`comblength' combined = `comb1'+","+`comb2'
}
if "`strtype1'" == "str" & "`strtype2'" ~= "str" {
gen str`comblength' combined = `comb1'+","+string(`comb2')
}
if "`strtype1'" ~= "str" & "`strtype2'" == "str" {
gen str`comblength' combined = string(`comb1')+","+`comb2'
}
if "`strtype1'" ~= "str" & "`strtype2'" ~= "str" {
gen str`comblength' combined = string(`comb1')+","+string(`comb2')
}
// Combine the variable labels and put them into a note for combined var.
lab var combined "`comb1' combined with `comb2'"
local varlab : variable label `comb1'
local labpiece1 : piece 1 73 of `"`varlab'"'
local labpiece2 : piece 2 73 of `"`varlab'"'
local varlab : variable label `comb2'
local labpiece3 : piece 1 73 of `"`varlab'"'
local labpiece4 : piece 2 73 of `"`varlab'"'
note combined: `labpiece1' `labpiece2' combined with ///
`labpiece3' `labpiece4'
if `combflag' == 1 {
local combflag = 2
}
if `combflag' == 0 {
local v = "combined"
local combflag = 1
}
}
// Do the remainder for all except the second combine variable.
if `combflag' ~= 2 {
// Calculate frequencies and percents - uses code from Nick Cox
// that he supplied for checkvar - more efficient than how I was doing it.
keep `v'
tempvar freq denom pct
gen `denom' = _N
sort `v'
by `v': gen `freq' = _N
by `v': gen `pct' = (`freq' / `denom') * 100
// Count number of distinct values in this var using egen's group function.
// Figure out whether to do a frequencies or summarize on this var,
// based on whether number of distinct values is <> summarize.
// Only collapse file if doing a frequencies (values < summarize)
// or if the user set a characteristic [freq] == "Yes". **********************************************
local freqchar : char `v'[freq] // get char [freq]
if `"`freqchar'"' == "yes" {
local freqchar = "Yes"
}
tempvar groupnum
tempvar numgrps
quietly egen `groupnum' = group(`v')
quietly egen `numgrps' = max(`groupnum')
if `numgrps' > `summarize' & `summarize' > 0 {
local values = `numgrps'
}
if `numgrps' <= `summarize' | `summarize' == 0 | "`strtype'" == "str" | `"`freqchar'"' == "Yes" {
quietly by `v': keep if _n == 1
local values = _N
}
// Check number of values for this variable against maxvalues.
local max = 0
if `maxvalues' <10 {
local maxvalues = 10
}
if `values' > `maxvalues' & `values'~=. {
local max = 1
}
if `values' ==. {
local max = 2
}
// Check number of values for this variable against summarize.
local tab = 0
if `values' > `summarize' & `summarize' > 0 & `"`freqchar'"' ~= "Yes"{
local tab = 1
}
local gotlabel : value label `v'
// Variable labels and notes
local varnote : char `v'[note1]
local skipnote : char `v'[note2]
local prenote : char `v'[note3]
local varlab : variable label `v'
if `"`varnote'"' ~= "" & "`notes'" ~= "" {
local varlabel `varnote'
}
else {
local varlabel `varlab'
if `"`varlab'"' == "" {
local varlabel " "
}
}
// If user supplied a value other than 0 for pagebreak,
// check whether there should be a page break here.
// If there's a skipnote or prenote, estimate its lines and add to newlines.
if `pagebreak' ~= 0 {
if `"`skipnote'"' ~= "" & "`notes'" ~= "" {
local notelength : length local skipnote
local notelines = `notelength'/100
local notelines = int(`notelines') + 1
local newlines = `newlines' + `notelines' + 2
}
if `"`prenote'"' ~= "" & "`notes'" ~= "" {
local notelength : length local prenote
local notelines = `notelength'/100
local notelines = int(`notelines') + 1
local newlines = `newlines' + `notelines' + 2
}
// If there's a var note or label, estimate its lines and add to newlines.
// This includes the var name and type, so it's a minimum of 3 lines.
local vlablength : length local varlabel
local vlablines = `vlablength'/60
local vlablines = int(`vlablines') + 1
local newlines = `newlines' + `vlablines' + 2
// If the number of values exceeds maxvalues, then max=1,
// so add 1 to newlines for the maxvalues Note in the variable label.
if `max' ==1 {
local newlines = `newlines' + 1
}
// Add 2 to newlines for the column header.
local newlines = `newlines' + 2
// Check length of value labels and add number of lines
// for each value to newlines.
if `"`gotlabel'"' ~= "" {
if `max' ~= 1 & `max' ~= 2 {
forval i = 1/`values' {
local x = `v'[`i']
local vallab : label (`v') `x'
local lablen : length local vallab
local lablines = `lablen'/60
local lablines = int(`lablines') + 1
local newlines = `newlines' + `lablines' + 1
}
}
if `max' == 1 {
forval i = 1/`values' {
if (`i' <=5) | (`i' >= (`values' - 4)) {
local x = `v'[`i']
local vallab : label (`v') `x'
local lablen : length local vallab
local lablines = `lablen'/60
local lablines = int(`lablines') + 1
local newlines = `newlines' + `lablines' + 1
}
}
}
if `max' == 2 {
local x = "."
local vallab = "."
local lablen = 1
local lablines = `lablen'/60
local lablines = int(`lablines') + 1
local newlines = `newlines' + `lablines' + 1
}
}
if `"`gotlabel'"' == "" {
if `max' ~= 1 {
local newlines = `newlines' + (`values' *2)
}
if `max' == 1 {
local newlines = `newlines' + 20
}
}
// Add 1 line for a space after this variable table.
local newlines = `newlines' + 1
// Add newlines to lines for this page and check against pagebreak.
// If it's larger, table for this variable won't fit on this page,
// so write a pagebreak.
local lines = `lines' + `newlines'
if `lines' >= `pagebreak' {
if `firstvar' ~= 1 {
file write `ho' `"
"' _n
}
if `newlines' <= `pagebreak' {
local lines = `newlines'
}
if `newlines' > `pagebreak' {
local lines = `newlines' - `pagebreak'
}
}
} // end of pagebreak check
// Check if there is a note3 and "notes" is turned on.
// If so, print it in its own table before note 2 and the header for the question itself.
if `"`prenote'"' ~= "" & "`notes'" ~= "" {
file write `ho' `"
"' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " """ `"`prenote'"' "" _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
}
// Check if there is a note2 and "notes" is turned on.
// If so, print it in its own table before the header for the question itself.
if `"`skipnote'"' ~= "" & "`notes'" ~= "" {
file write `ho' `""' _n
file write `ho' " " _n
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " """ `"`skipnote'"' "" _n
file write `ho' " | " _n
file write `ho' "
" _n
file write `ho' " " _n
file write `ho' "
" _n
}
// Start a new table for this variable.
file write `ho' `""' _n
file write `ho' " " _n
// Figure out size of strings.
local vartype : type `v'
local strtype = substr("`vartype'",1,3)
if "`strtype'" == "str" {
local lengthtype = length("`vartype'") - 3
local strlength = substr("`vartype'",4,`lengthtype')
}
// If "type" is not turned on, then create universal format
// for variable storage (num or string, and length).
// Otherwise, print Stata's variable type (byte, float, etc.).
if "`type'" == "" {
if "`vartype'" == "byte" {
local vartype = "Num"
}
else if "`vartype'" == "int" {
local vartype = "Num"
}
else if "`vartype'" == "long" {
local vartype = "Num"
}
else if "`vartype'" == "float" {
local vartype = "Num"
}
else if "`vartype'" == "double" {
local vartype = "Num"
}
else {
local stype = "Char "
local vartype = "`stype'"
}
}
// Check whether user wants the variable name printed in upper case.
local varname = "`v'"
if "`upper'" != "" {
local varname = upper("`v'")
}
// HEADER: print the variable name and label for each variable.
// Check if there is a note1 and "notes" is turned on.
// If so, assume note1 is the text of the question, and
// print it as the header information.
// If note1 doesn't exist, or "notes" isn't turned on,
// print the variable label (which might be a null string).
// Print variable name and type after the note/label.
// tab=0 is frequencies, tab=1 is means
if `tab' == 0 | "`strtype'" == "str" {
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " ""`varname'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " "" " _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""`vartype'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""`varlabel'" _n
if `max' == 1 & `"`freqchar'"' ~= "Yes" file write `ho' " "" `maxlabel'" _n
file write `ho' " | " _n
file write `ho' "
" _n
}
if `tab' == 1 & "`strtype'" ~= "str" {
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " ""`varname'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""`vartype'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " "" " _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " "" " _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""`varlabel'" _n
file write `ho' " | " _n
file write `ho' "
" _n
}
// Write column headers
// If values <= summarize or variable is string, write headers for frequency, percent, value, and label
if `tab' == 0 | "`strtype'" == "str" {
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " ""Frequency" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Percent" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Value" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Label" _n
file write `ho' " | " _n
file write `ho' "
" _n
}
// If values > summarize, write headers for frequency, mean, std dev, min, and max
if `tab' == 1 & "`strtype'" ~= "str" {
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " ""Frequency" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Mean" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Std Dev" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Min" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " ""Max" _n
file write `ho' " | " _n
file write `ho' "
" _n
}
if `"`gotlabel'"' ~= "" {
local gotlabel = "Yes"
}
else {
local gotlabel = "No"
}
// Before first call to DispFreq, replace null value of Vallabel with "No" so the argument has a value.
if "`vallabel'" == "" {
local vallabel = "No"
}
// If values <= maxvalues, and values <= summarize (or summarize = 0), display frequencies for all values.
// When calling DispFreq, "strlength" should be the last argument,
// since it can be a null string (the others always have a value).
local range = "0"
if ((`max' == 0 & (`tab' == 0 | "`strtype'" == "str")) | `"`freqchar'"' == "Yes") {
forval i = 1/`values' {
DispFreq `ho' `v' `i' `range' `freq' `pct' `pprecision' `fprecision' `gotlabel' `vallabel' `vartype' `strtype' `stringmax' `strlength'
}
}
// If values > maxvalues, and values <= summarize (or summarize = 0), display frequencies of only smallest 5 and largest 5 values.
// Display a row showing the frequency, percent, and range of the omitted values.
*set tracedepth 1
*set trace on
if ((`max' == 1 & (`tab' == 0 | "`strtype'" == "str")) & `"`freqchar'"' ~= "Yes") {
forval i = 1/`values' {
if (`i' <=5) {
DispFreq `ho' `v' `i' `range' `freq' `pct' `pprecision' `fprecision' `gotlabel' `vallabel' `vartype' `strtype' `stringmax' `strlength'
}
if (`i' ==6) {
local templabel = "`gotlabel'"
local gotlabel = "Range"
local x = `v'[`i']
local range = "`x'"
local rangefreq = `freq'[`i']
local rangepct = `pct'[`i']
}
if (`i' == (`values' - 5) & `i' == 6) {
local rndprec = 1
local zeros = "00000000000000000000000000000000000000000000000000"
if `fprecision' != 0 {
local numzero = `fprecision'-1
local nzero = substr("`zeros'",1,`numzero')
local rndprec = "0." + "`nzero'" + "1"
}
if "`strtype'" ~= "str" & strpos("`range'",".")~=0 {
local range2 = round(`range',`rndprec')
local rangelength = strpos("`range2'",".")+`fprecision'
local range = substr("`range2'",1,`rangelength')
}
DispFreq `ho' `v' `i' "`range'" `rangefreq' `rangepct' `pprecision' `fprecision' `gotlabel' `vallabel' `vartype' `strtype' `stringmax' `strlength'
}
if (`i' > 6 & `i' < (`values' - 5)) {
local rangefreq = `rangefreq' + `freq'[`i']
local rangepct = `rangepct' + `pct'[`i']
}
if (`i' == (`values' - 5) & `i' ~= 6) {
local x = `v'[`i']
local rndprec = 1
local zeros = "00000000000000000000000000000000000000000000000000"
if `fprecision' != 0 {
local numzero = `fprecision'-1
local nzero = substr("`zeros'",1,`numzero')
local rndprec = "0." + "`nzero'" + "1"
}
if "`strtype'" == "str" {
local range = "Values omitted"
}
******************************************
if "`strtype'" ~= "str" {
local range2 = round(`range',`rndprec')
if strpos("`range2'",".")~=0 {
local rangelength = strpos("`range2'",".")+`fprecision'
local range3 = substr("`range2'",1,`rangelength')
}
if strpos("`range2'",".")==0 {
local range3 = `range2'
}
if strpos("`x'",".")~=0 {
local x = round(`x',`rndprec')
local xlength = strpos("`x'",".")+`fprecision'
local x3 = substr("`x'",1,`xlength')
}
if strpos("`x'",".")==0 {
local x3 = `x'
}
local range = "`range3'" + "-" + "`x3'"
}
local rangefreq = `rangefreq' + `freq'[`i']
local rangepct = `rangepct' + `pct'[`i']
DispFreq `ho' `v' `i' "`range'" `rangefreq' `rangepct' `pprecision' `fprecision' `gotlabel' `vallabel' `vartype' `strtype' `stringmax' `strlength'
}
if (`i' >= (`values' - 4)) {
local gotlabel = "`templabel'"
local range = "0"
DispFreq `ho' `v' `i' "`range'" `freq' `pct' `pprecision' `fprecision' `gotlabel' `vallabel' `vartype' `strtype' `stringmax' `strlength'
}
}
}
*set trace off
// If values > summarize, display summary statistics (regardless of maxvalues).
if `tab' == 1 & "`strtype'" ~= "str" {
quietly su `v'
local num = `r(N)'
if `num' ~= 0 {
local mean = `r(mean)'
local sd = `r(sd)'
local min = `r(min)'
local max = `r(max)'
}
if `num' == 0 {
local mean = "."
local sd = "."
local min = "."
local max = "."
}
DispSum `ho' `num' `mean' `sd' `min' `max' `sprecision'
}
// Restore the data to get another variable, and preserve it again.
restore, preserve
// Close the table tags for this variable.
file write `ho' " " _n
file write `ho' "
" _n
// Put a blank line after writing each variable.
file write `ho' "
"
} // end of loop for combflag ~= 2
if `combflag' == 2 {
local combflag = 0
}
if `firstvar' == 1 {
local firstvar = 0
}
} // end of varlist loop
// *******************************************************
// ***** End of loop over each variable in `varlist' *****
// *******************************************************
// Close the body tag and close the output file.
file write `ho' "" _n "" _n
file close `ho'
// If we got this far, the temporary html file has been written,
// and we can copy it into the permanent "using" filename.
local tempflag = 0
capture confirm file "`tempho'"
if _rc==0 {
local tempflag = 1
}
if `tempflag' == 1 {
if "`replace'" == "replace" & `usingflag' == 1 {
copy "`tempho'" `"`using'.html"', replace
di as text "File `using'.html replaced"
}
else {
copy "`tempho'" `"`using'.html"'
di as text "File `using'.html created"
}
}
else {
di as error "The html file was not written."
di as text "Please contact phil_bardsley@unc.edu"
}
end
program define DispFreq
args ho v i range freq pct pprecision fprecision gotlabel vallabel vartype strtype stringmax strlength
*set tracedepth 1
*set trace on
// If v is a string longer than 10 characters,
// trim leading and trailing blanks, and truncate to
// first 10 characters for display.
// If v is a string and missing, change its value
// to a single blank, so the cell shows up in html table.
if "`strtype'" == "str" {
if `stringmax' > 0 {
quietly replace `v' = substr(trim(`v'),1,`stringmax') in `i'
}
if `v' == "" {
quietly replace `v' = " " in `i'
}
}
// Initialize vallab to blank.
// Put the current value's label into vallab if there is one.
// Put the current value's value into vallab if vallabel is turned on and there is no label.
// Write the word "Missing" if the value is a missing numeric or string.
local vallab = " "
local flength = `pprecision' + 4
local pfmt = "%`flength'.`pprecision'f"
if "`gotlabel'" ~= "Range" {
local x = `v'[`i']
local f = `freq'[`i']
local p = `pct'[`i']
}
if "`gotlabel'" == "Range" {
local x = "`range'"
local f = `freq'
local p = `pct'
local vallab = "NOTE: Range of values omitted from display"
}
local vx = "`v'"
local vfmt : format `vx'
local vtx : type `vx'
local fmtdot = strpos("`vfmt'",".")-2
local fmt1 = substr("`vfmt'",2,`fmtdot')
* local fmt1 = `fmt1' + `fprecision' + 20
local fmt1 = `fmt1' + `fprecision'
local rndprec = 1*10^-`fprecision'
if ("`vtx'" == "float" | "`vtx'" == "double") {
if `fprecision' != 0 {
local vfmt = "%" + "`fmt1'" + "." + "`fprecision'" + "f"
}
if `fprecision' == 0 {
local vfmt = "%" + "`fmt1'" + "." + "0f"
}
}
/*
if "`gotlabel'" == "Yes" {
local vallab : label (`v') `x', strict
if "`vallab'" == "" & "`vallabel'" ~= "No" {
local vallab = string(round(`x',`rndprec'))
}
if "`vallab'" == "" & "`vallabel'" == "No" {
local vallab = " "
}
}
if "`gotlabel'" == "No" & "`strtype'" ~= "str" {
if "`vallabel'" ~= "No" {
local vallab = string(round(`x',`rndprec'))
}
if "`vallabel'" == "No" {
local vallab = " "
}
}
if "`strtype'" == "str" {
if "`vallabel'" ~= "No" {
local vallab = "`x'"
}
if "`vallabel'" == "No" {
local vallab = " "
}
}
*/
// Write line v[i] (frequencies, percent, value, and label).
// (Note: parentheses instead of quotes are required for the percent to be formatted properly.)
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " " "`f'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " " `pfmt' (`p') "%" _n
file write `ho' " | " _n
file write `ho' `" "' _n
if "`vtx'" == "float" | "`vtx'" == "double" {
if "`gotlabel'" ~= "Range" {
file write `ho' " " `vfmt' (`x') _n
}
if "`gotlabel'" == "Range" {
file write `ho' " " `"`x'"' _n
}
}
else {
file write `ho' " " `"`x'"' _n
}
file write `ho' " | " _n
file write `ho' `" "' _n
if "`gotlabel'" == "Yes" {
local vallab : label (`v') `x', strict
if "`vallab'" == "" & "`vallabel'" ~= "No" {
if `x' ~= . {
file write `ho' " " `vfmt' (`x') _n
}
if `x' == . {
file write `ho' " " "Missing" _n
}
}
if "`vallab'" == "" & "`vallabel'" == "No" {
if `x' ~= . {
file write `ho' " " " " _n
}
if `x' == . {
file write `ho' " " "Missing" _n
}
}
if "`vallab'" ~= "" {
file write `ho' " " "`vallab'" _n
}
}
if "`gotlabel'" == "No" & "`strtype'" ~= "str" {
if "`vallabel'" ~= "No" {
if `x' ~= . {
file write `ho' " " `vfmt' (`x') _n
}
if `x' == . {
file write `ho' " " "Missing" _n
}
}
if "`vallabel'" == "No" {
file write `ho' " " " " _n
}
}
if "`gotlabel'" == "Range" & "`strtype'" ~= "str" {
file write `ho' " " "`vallab'" _n
}
if "`strtype'" == "str" {
if "`vallabel'" ~= "No" {
file write `ho' " " "`x'" _n
}
if "`vallabel'" == "No" {
file write `ho' " " " " _n
}
}
file write `ho' " | " _n
file write `ho' "
" _n
*set trace off
end
program define DispSum
args ho num mean sd min max sprecision
// Write line v[i] (, percent, value, and label).
// (Note: parentheses instead of quotes are required when specifying a format, such as sfmt.)
if `sprecision' != 0 {
local sfmt = "%" + "23" + "." + "`sprecision'" + "f"
}
if `sprecision' == 0 {
local sfmt = "%" + "23" + "." + "0f"
}
file write `ho' " " _n
file write `ho' `" "' _n
file write `ho' " " "`num'" _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " " `sfmt' (`mean') _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " " `sfmt' (`sd') _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " " `sfmt' (`min') _n
file write `ho' " | " _n
file write `ho' `" "' _n
file write `ho' " " `sfmt' (`max') _n
file write `ho' " | " _n
file write `ho' "
" _n
end
exit
HISTORY
Version 1.9:
23Jun2010
looks for variable characteristic varname[freq] == "Yes", and if it finds that value it prints
all values for the variable regardless of the settings of maxvalues() or summarize()
define the characteristics like this:
foreach v of varlist var1 var2 var3 ... {
char def `v'[freq] Yes
}
Version 1.8:
13Mar2010
adds option to copy value into label field instead of making it automatic
reverts to using the format in the dataset instead of imposing a format - if the user
wants to avoid scientific notation he must format the variable himself
Version 1.7:
23Feb2010
formats the label to round those long ugly numbers when the values are stored imprecisely
added 20 to formats to get rid of scientific notation: local fmt1 = `fmt1' + `fprecision' + 20
this is a tradeoff - I used the variable's current format up to now, but in a codebook,
scientific notation is not useful, but this approach is misleading in that the format
in the data is much shorter - the real data won't behave the way the codebook suggests
03nov2009
handles string variables much better now
writes value as label when there's no value label
11dec2008
write the name of the current variable to the results screen, so that if there's a problem with the
note or label, the user knows which variable has the problem
27feb2008
converted some compound quotes to single quotes for use in version 10
28nov2007
bug fix for variables with all missing values
11sep2007
remove 244 character limit on notes
option to specify decimal display precision for floating point values (fprecision option)
option to specify decimal display precision for summarized variables (sprecision option)
upper case display of variable names (upper option)
Version 1.3:
16jan2007
added row with range and n when all rows are not displayed (smallest 5/largest 5 condition)
fixed problem when all obs have missing values for a variable
Version 1.2:
10dec2006
added note 3 to display more info, such as section headings, pretext, interviewer instructions, etc.
Version 1.1:
05jan2005
added summarize option to display summary statistics
20jan2004
fixed null variable label error
no longer truncates string values, and added option to substr them (stringmax)
uses display format to write float and double variable values
reduced maxvalues from 100 to 10
Version 1.0 (published in SSC Archive 18jan2004):
08jan2004
added page-break option for printing
09dec2003
fixed message when "replace" option used with new files
improved efficiency using Nick Cox's code (intended for checkvar)
(got rid of egen altogether)
24nov2003
made combined-variable logic a little easier to follow
replaced egen concatenation with string operator concatenation
20jun2003
long numeric values will push the column over a bit - not sure if I want to
truncate them, since they'll be rare.
handles:
strings: first 10 characters (trims leading and trailing blanks,
then substrings first 10 characters of what's left),
but this is easily extended
variable labels: 80 characters (max in Stata/SE 8)
value labels: 244 characters (max in Stata/SE 8)
notes: the whole thing (max in Stata/SE 8 is 67,784)