*! version 1.1.0 PR 28Oct1999. (STB-55: ip9.1) program define byvar, rclass /* byvar [, options] : stata_cmd */ version 6 tokenize `"`0'"', parse(" ,:") while `"`1'"'!="," & `"`1'"'!=":" { if `"`1'"'=="" { error 198 } local bylist `bylist' `1' mac shift } if trim("`bylist'")=="" { error 198 } if `"`1'"'=="," { mac shift while `"`1'"'!=":" { if `"`1'"'=="" { error 198 } local optlist `optlist' `1' mac shift } } mac shift /* the colon */ local command `*' /* the Stata cmd */ unab bylist: `bylist' tokenize `"`command'"', parse(",") local cmd1 `1' mac shift local cmd2 `*' local pif=index(`"`cmd1'"', " if ") if `pif'>0 { local cmd11=substr(`"`cmd1'"',1,`pif') local cmd12=substr(`"`cmd1'"',`pif'+4,.) local ifalso " & " } else local cmd11 `cmd1' local 0 ", `optlist'" syntax, [ E(str) R(str) B(str) SE(str) GRoup(str) GEnerate /* */ Tabulate REturn Missing Pause noLabel Unique ] if "`group'"!="" { confirm new var `group' } if "`unique'"!="" & "`generat'"=="" { di in red "unique valid only with generate" exit 198 } local s1 `e' local L1 E local s2 `r' local L2 R local s3 `b' local L3 B local s4 `se' local L4 S local tostore=`"`s1'`s2'`s3'`s4'"'!="" if !`tostore' & "`generat'`return'`tabulat'"!="" { di in red "nothing to generate, return or tabulate" exit 198 } if `tostore' & "`generat'`return'`tabulat'"=="" { di in bl "(tabulate assumed)" local tabulat tabulate } local tab="`tabulat'"!="" & `tostore' /* Number and count the groups */ quietly { /* Default is to exclude missing groups in bylist from analysis. Their corresponding group codes are set to missing and sorted to end of data. */ tempvar grp first marksample touse if "`missing'"=="" { markout `touse' `bylist', strok replace `touse'=. if `touse'==0 } sort `touse' `bylist' by `touse' `bylist': gen byte `first'=1 if _n==1 & `touse'==1 gen int `grp'=sum(`first') if `touse'==1 drop `touse' sum `grp' local GRP=r(max) if `GRP'==0 { noisily error 2000 } local itemlen 14 /* Extract group-defining values of bylist variables and store in macros */ local nby : word count `bylist' if `tab' { noi di local dashes } tempvar index gen long `index'=. local i 1 while `i'<=`GRP' { replace `index'=sum(_n*(`grp'==`i' & `first'==1)) local j=`index'[_N] local k 1 while `k'<=`nby' { local byvar`k' : word `k' of `bylist' local vallab: value label `byvar`k'' local byval=`byvar`k''[`j'] if "`vallab'"!="" & "`label'"!="nolabel" { local by`i'`k': label `vallab' `byval' } else local by`i'`k' `byval' if `i'==1 & `tab' { local dashes "`dashes'---------" noi di in gr %-9s "`byvar`k''" _c } local k=`k'+1 } local i=`i'+1 } drop `index' } if `tab' { di in gr " |" _c local dashes "`dashes'-+" } /* Parse and record items for storage */ local j 1 while `j'<=4 { local i 1 if `"`s`j''"'!="" { tokenize `"`s`j''"' * take care of embedded quotes local k 1 local quote 0 while `"`1'"'!="" { local sk`k' `sk`k'' `1' if index(`"`1'"',`"""')!=0 { * detected quote if `quote' { local k=`k'+1 } local quote=!`quote' /* toggle quote */ } else { if !`quote' { local k=`k'+1 } } mac shift } if `quote' { di in red "unmatched quotes in " `"`s`j''"' exit 198 } local l 1 while `l'<`k' { * 1=item, [ 2="=", 3=description of item ], 4=null tokenize `"`sk`l''"', parse("=") local sk`l' if `"`4'"'!="" { di in red "invalid " `"`sk`l''"' exit 198 } local st`j'`i' `1' if `"`3'"'=="" { if `j'==1 { local lab e(`1') } else if `j'==2 { local lab r(`1') } else if `j'==3 { local lab _b[`1'] } else if `j'==4 { local lab _se[`1'] } } else { local lab=substr(`"`3'"',1,`itemlen'-1) } if "`generat'"!="" { mk_name `L`j'' `1' 6 local `L`j''_`i' `s(name)' qui gen double ``L`j''_`i''=. lab var ``L`j''_`i'' `"`lab' by `bylist'"' } if `tab' { local dashes "`dashes'--------------" local skip=`itemlen'-length(`"`lab'"') di in gr _skip(`skip') `"`lab'"' _c } local i=`i'+1 local l=`l'+1 } } local n`j'=`i'-1 local j=`j'+1 } if `tab' { di _n in gr "`dashes'" } /* Perform calcs */ if `tab' { local show quietly } else local show noisily tempname thing local i 1 while `i'<=`GRP' { /* i indexes members of groups implied by bylist */ if !`tab' { di in bl _n "-> " _c local k 1 while `k'<=`nby' { di in bl "`byvar`k''==`by`i'`k'' " _c local k=`k'+1 } di } capture `show' `cmd11' if `grp'==`i' `ifalso' `cmd12' `cmd2' local rc=_rc if "`pause'"!="" { more } if `tab' { local k 1 while `k'<=`nby' { di %-9s substr("`by`i'`k''",1,8) _c local k=`k'+1 } di in gr " |" _c } local k 1 while `k'<=4 { /* k indexes the 4 types of thing to be stored */ if `n`k''>0 { local l 1 while `l'<=`n`k'' { /* l indexes # of thing */ if `rc'==0 { if `k'==1 { scalar `thing'=e(`st`k'`l'') } else if `k'==2 { scalar `thing'=r(`st`k'`l'') } else if `k'==3 { scalar `thing'=_b[`st`k'`l''] } else if `k'==4 { scalar `thing'=_se[`st`k'`l''] } } else scalar `thing'=. if "`generat'"!="" { if "`unique'"=="" { qui replace ``L`k''_`l''=`thing' if `grp'==`i' } else qui replace ``L`k''_`l''=`thing' /* */ if `grp'==`i' & `first'==1 } if "`return'"!="" { * gp refers to subgroup (level) of the byvar(s) local r `L`k''`l'gp`i' return scalar `r'=`thing' } if `tab' { di _skip(4) in ye %10.0g `thing' _c } local l=`l'+1 } } local k=`k'+1 } if `tab' { di } local i=`i'+1 } quietly if "`generat'"!="" { local k 1 while `k'<=4 { /* k indexes type of thing stored */ if `n`k''>0 { local i 1 while `i'<=`n`k'' { /* i indexes item in list of things */ compress ``L`k''_`i'' return local `L`k''_`i' ``L`k''_`i'' local i=`i'+1 } } local k=`k'+1 } } if "`group'"!="" { cap drop `group' rename `grp' `group' lab var `group' "group by `bylist'" } return scalar byvar_g=`GRP' end program define mk_name, sclass /* meaning make_unique_name <#_chars> */ version 6 args letter base numchar sret clear local name = substr("`letter'`base'",1,`numchar'+1) xi_mkun2 `name'_ end program define xi_mkun2, sclass /* meaning make_unique_name */ args name local totry "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" local lentot=length("`totry'") local l 0 local len = length("`name'") capture list `name'* in 1 /* try name out */ while _rc==0 { if `l'==`lentot' { di in red "too many terms---limit is " `lentot'+1 exit 499 } local l=`l'+1 local name = substr("`name'",1,`len'-1)+substr("`totry'",`l',1) capture list `name'* in 1 } sret local name "`name'" end