*! version 1.0.0 23oct1997 statalist program define _ttest version 5.0 /* This command consists of a group of helper commands for ttest and sdtest. _ttest one _ttest two _ttest by _ttest check _ttest header _ttest table _ttest center */ local cmd "`1'" macro shift if "`cmd'"=="center" { _center "`1'" "`2'" "`3'" } else _`cmd' `*' end program define _one /* Computes #obs, mean, sd of a variable for a one-sample test. Then calls -ttesti- or -sdtesti-. Syntax: _one {ttesti|sdtesti} level touse xvar Ho The first group is defined to be the lesser value of the -by- variable. */ local cmd "`1'" local level "`2'" local touse "`3'" local xvar "`4'" local Ho "`5'" quietly summarize `xvar' if `touse' local n = _result(1) local m = _result(3) local s = sqrt(_result(4)) `cmd' `n' `m' `s' `Ho', xname(`xvar') level(`level') end program define _two /* Computes #obs, mean, sd of variable1 and variable2 for a two-sample test. Then calls -ttesti- or -sdtesti-. Syntax: _two {ttesti|sdtesti} level touse xvar1 xvar2 [options] */ local cmd "`1'" local level "`2'" local touse "`3'" local xvar1 "`4'" local xvar2 "`5'" macro shift 5 local options "`*'" quietly summarize `xvar1' if `touse' local n1 = _result(1) local m1 = _result(3) local s1 = sqrt(_result(4)) unabbrev `xvar2' local xvar2 "$S_1" quietly summarize `xvar2' if `touse' local n2 = _result(1) local m2 = _result(3) local s2 = sqrt(_result(4)) `cmd' `n1' `m1' `s1' `n2' `m2' `s2', xname(`xvar1') yname(`xvar2') /* */ level(`level') `options' end program define _by /* Computes #obs, mean, sd of a variable for two groups defined by a -by- variable. Then calls -ttesti- or -sdtesti-. Syntax: _by {ttesti|sdtesti} level touse xvar by [options] The first group is defined to be the lesser value of the -by- variable. */ local cmd "`1'" local level "`2'" local touse "`3'" local xvar "`4'" local by "`5'" macro shift 5 local options "`*'" /* Markout `xvar'. */ markout `touse' `xvar' /* If `by' is a string variable, create a numeric one. */ capture confirm string variable `by' if _rc == 0 { ByString `n1' `m1' `s1' `n2' `m2' `s2' `touse' `xvar' `by' exit } /* Here only if `by' is numeric. */ markout `touse' `by' tempname val1 val2 quietly { summarize `by' if `touse' if _result(1) == 0 { noisily error 2000 } scalar `val1' = _result(5) scalar `val2' = _result(6) /* Check that there are exactly 2 groups. */ if `val1' == `val2' { di in red "1 group found, 2 required" exit 420 } count if `by'!=`val1' & `by'!=`val2' & `touse' if _result(1) != 0 { di in red "more than 2 groups found, only 2 allowed" exit 420 } /* Get #obs, mean, and sd for first group. */ summarize `xvar' if `by'==`val1' & `touse' local n1 = _result(1) local m1 = _result(3) local s1 = sqrt(_result(4)) /* Get #obs, mean, and sd for second group. */ summarize `xvar' if `by'==`val2' & `touse' local n2 = _result(1) local m2 = _result(3) local s2 = sqrt(_result(4)) /* Get group labels. */ local lab1 = `val1' local lab2 = `val2' local bylab : value label `by' if "`bylab'"!="" { local lab1 : label `bylab' `lab1' if "`lab1'"=="" { local lab1 = `val1' } local lab2 : label `bylab' `lab2' if "`lab2'"=="" { local lab2 = `val2' } } local lab1 = substr("`lab1'",1,8) local lab2 = substr("`lab2'",1,8) } `cmd' `n1' `m1' `s1' `n2' `m2' `s2', xname(`lab1') yname(`lab2') /* */ level(`level') `options' end program define ByString local n1 "`1'" local m1 "`2'" local s1 "`3'" local n2 "`4'" local m2 "`5'" local s2 "`6'" local touse "`7'" local xvar "`8'" local by "`9'" /* Markout. */ markout `touse' `by', strok tempvar obs quietly { /* Get `by' groups without sorting (which is unnecessarily slow!). */ gen long `obs' if `touse' summarize `obs', meanonly if _result(1) = 0 { noisily error 2000 } local val1 = `by'[_result(5)] replace `obs' = . if `by'=="`val1'" summarize `obs', meanonly if _result(1) = 0 { di in red "1 group found, 2 required" exit 420 } local val2 = `by'[_result(5)] replace `obs' = . if `by'=="`val2'" summarize `obs', meanonly if _result(1) != 0 { di in red "more than 2 groups found, only 2 allowed" exit 420 } /* Make it so that "`val1'" < "`val2'". */ if "`val1'" > "`val2'" { local temp "`val1'" local val1 "`val2'" local val2 "`temp'" } /* Get #obs, mean, and sd for first group. */ summarize `xvar' if `by'=="`val1'" & `touse' scalar `n1' = _result(1) scalar `m1' = _result(3) scalar `s1' = sqrt(_result(4)) /* Get #obs, mean, and sd for second group. */ summarize `xvar' if `by'=="`val2'" & `touse' scalar `n2' = _result(1) scalar `m2' = _result(3) scalar `s2' = sqrt(_result(4)) /* Put group labels in global macros. */ global S_1 = substr("`val1'",1,8) global S_2 = substr("`val2'",1,8) end program define _check /* This program checks sense of #obs, mean, and standard deviation for -ttesti- and -sdtesti-. Syntax: _check {ttest|sdtest} {one|first|second} #1 #2 #3 [#4] where one, first, or second refers to, respectively, a one-sample test, first sample of a two-sample test, or second sample of a two-sample test, and #1 = #obs, #2 = mean, #3 = standard deviation, and #4 = hypothesized value. */ local cmd "`1'" /* ttest or sdtest */ local sample "`2'" /* one, first, or second */ local n "`3'" /* #obs */ local m "`4'" /* mean */ local s "`5'" /* standard deviation */ local h "`6'" /* hypothesized value (only if `sample' is "one") */ /* Check `n' number of observations. */ if "`n'"=="." { if "`sample'"!="one" { di in red "number of observations of `nsamp' sample" /* */ " is missing" } else di in red "number of observations is missing" exit 416 } confirm integer number `n' if `n' < 0 { if "`sample'"!="one" { di in red "number of observations in `nsamp' sample" /* */ " is negative" } else di in red "number of observations is negative" exit 411 } if `n' == 0 { if "`sample'"!="one" { di in red "`nsamp' sample has no observations" exit 2000 } error 2000 } /* Check `m' mean. */ if "`m'"=="." { if "`cmd'"=="ttest" { if "`sample'"!="one" { di in red "mean of `nsamp' sample is missing" } else di in red "mean is missing" exit 416 } } else confirm number `m' /* Check `s' standard deviation. */ if "`s'"=="." { if `n' != 1 { if "`sample'"!="one" { di in red "standard deviation of `nsamp' " /* */ "sample is missing" } else di in red "standard deviation is missing" exit 416 } } else { confirm number `s' if `s' < 0 { if "`sample'"!="one" { di in red "`nsamp' sample has a negative " /* */ "standard deviation" } else di in red "standard deviation is negative" exit 411 } if `n' == 1 & `s' != 0 { if "`sample'"!="one" { di in red "`nsamp' sample has only one " /* */ "observation, but positive standard " /* */ "deviation" } else di in red "only one observation, but positive " /* */ "standard deviation" exit 499 } } /* Check next number if `sample' is "one". */ if "`sample'"!="one" { exit } if "`h'"=="." { di red "hypothesized value is missing" exit 416 } confirm number `h' if "`cmd'"=="sdtest" & `h' < 0 { di in red "hypothesized standard deviation is negative" exit 411 } end program define _header local level "`1'" local xname "`2'" if "`xname'"!="" { capture confirm variable `xname' if _rc == 0 { local col1 "Variable" } else local col1 " Group" } di _n in gr _dup(78) "-" _n "`col1'" _col(10) "|" _col(16) "Obs" /* */ _col(27) "Mean" _col(35) "Std. Err." _col(47) "Std. Dev." /* */ _col(59) "[`level'% Conf. Interval]" _n _dup(9) "-" "+" _dup(68) "-" end /* 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++|++++ | Variable | Obs Mean Std. Err. Std. Dev. [95% Conf. Interval] - ---------+-------------------------------------------------------------------- mpg | 1234567 123456789 123456789 123456789 123456789 123456789 */ program define _table /* This program displays table with information about mean, etc. Syntax: _table level name #obs mean sd [se] [df] Note: expressions without blanks are OK. */ local level "`1'" local name "`2'" local n "(`3')" local mean "(`4')" local sd "(`5')" local se "`6'" local df "`7'" if `n' == 1 | `n' == . { local sd = . local se = . } if "`se'"=="" { local se = `sd'/sqrt(`n') } if "`df'"=="" { local df = `n' - 1 } local q = invt(`df',`level'/100) local begin = 9 - length("`name'") #delimit ; di in gr _col(`begin') "`name'" _col(10) "|" in ye _col(12) %7.0f `n' _col(22) %9.0g `mean' _col(34) %9.0g `se' _col(46) %9.0g `sd' _col(58) %9.0g `mean'-`q'*(`se') _col(70) %9.0g `mean'+`q'*(`se') ; #delimit cr end program define _center /* Syntax: _center "string" [displays centered "string"] _center "string1" "string2" "string3" [displays centered in 3 columns] @ character in string toggles color from green to yellow (or from yellow to green); green is the default and initial color. Example: "green @yellow@ green @yellow@" */ local left 12 /* columns centered about these values */ local mid 39 local right 66 if "`2'"=="" { Display "`1'" `mid' 0 di /* newline */ exit } Display "`1'" `left' 0 Display "`2'" `mid' $S_1 Display "`3'" `right' $S_1 di /* newline */ end program define Display local string "`1'" local center "`2'" /* value to center about */ local last "`3'" /* column of last character printed */ Length "`string'" local length $S_1 local skip = max((`last'!=0), `center' - int(`length'/2) - 1 - `last') di _skip(`skip') _c /* skip spaces */ Print "`string'" /* print out string */ global S_1 = `last'+`skip'+`length' /* last character printed */ end program define Length local length 0 local string "`1'" while "`string'"!="" { local i = index("`string'","@") if `i' == 0 { local length = `length' + length("`string'") local string } else { local length = `length' + `i' - 1 Substr "`string'" `i'+1 . local string "$S_1" } } global S_1 `length' end program define Print local string "`1'" local color "gr" while "`string'"!="" { local i = index("`string'","@") if `i' == 0 { di in `color' "`string'" _c local string } else { Substr "`string'" 1 `i'-1 di in `color' "$S_1" _c if "`color'"=="gr" { local color ye } else local color gr Substr "`string'" `i'+1 . local string "$S_1" } } end program define Substr local string "`1'" local a = `2' local b = `3' if `b' == . { local b = length("`string'") - `a' + 1 } local sub = substr("`string'",`a',`b') local lsub = length("`sub'") if `lsub' < `b' { local nblank = `b' - `lsub' local blanks : di _dup(`nblank') " " local sub "`blanks'`sub'" } global S_1 "`sub'" end exit