/* version 2, October 25, 2003, allen buxton*/ /*capture program drop tarow*/ program define tarow, rclass version 7.0 syntax varlist [if] [in] [, Options_tabulate(string) Row_options_tabulate(string)] tempvar touse mark `touse' `if' `in' qui count if `touse' if r(N)==0 { error 2000 /* no observations */ } local varlstA `"`varlist'"' local tabopts `"`options_tabulate'"' local rtabopts `"`row_options_tabulate'"' local opt_missing_flag = 0 foreach Opt in `tabopts' { /*display `"=====!!!====="'*/ /*display `"option: `Opt'"'*/ local Option_i = lower(`"`Opt'"') /* I am assumming that single "m" stands for missing, provided that "m" is not "mat..." */ if index(`"`Option_i'"',`"mat"') ==0 { if substr(`"`Option_i'"',1,1) == `"m"' { local opt_missing_flag = 1 } } } tokenize `varlstA' local n_var : word count `varlstA' if `n_var' == 2 { local twovarentered=1 } else if `n_var' ~= 2 { local twovarentered=0 } if `n_var' == 1 { error 102 /* too few variables entered */ } else if `n_var' >= 3 { error 103 /* too many variables entered */ } local var1 `1' /* row variable */ local var2 `2' /* column variable */ local typ1 : type `var1' local typ2 : type `var2' if `"`typ1'"' == `"byte"' { local typ1ok = 1 } else if `"`typ1'"' == `"int"' { local typ1ok = 1 } else if `"`typ1'"' == `"long"' { local typ1ok = 1 } else if `"`typ1'"' == `"float"' { local typ1ok = 1 } else if `"`typ1'"' == `"double"' { local typ1ok = 1 } else { local typ1ok=0 } if `"`typ2'"' == `"byte"' { local typ2ok = 1 } else if `"`typ2'"' == `"int"' { local typ2ok = 1 } else if `"`typ2'"' == `"long"' { local typ2ok = 1 } else if `"`typ2'"' == `"float"' { local typ2ok = 1 } else if `"`typ2'"' == `"double"' { local typ2ok = 1 } else { local typ2ok=0 } if `typ1ok'==0 | `typ2ok'==0 { display `"currently, only numeric variables are required"' error 459 } tempvar rowvar tempvar colvar *display `" variable list: "' `"`varlstA'"' *display `" variable list: "' `"`var1'"' *display `" variable type: "' `"`typ1'"' *display `" variable type: "' `"`typ1ok'"' *display `" variable list: "' `"`var2'"' *display `" variable type: "' `"`typ2'"' *display `" variable type: "' `"`typ2ok'"' *display `" num of var: "' `"`n_var'"' *display `"Tabulate options: "' `"`tabopts'"' *display `"Row tabulate opt: "' `"`rtabopts'"' tempvar otherrow tempvar tempA tempvar tempB tempvar tempC tempname m1 tempname m2 tempname m3 if `"`tabopts'"' == `""' { tabulate `var1' `var2' if `touse' } else { tabulate `var1' `var2' if `touse', `tabopts' } display `""' /* I shall unconditionally do the following to get the matricies of the main table */ /* yet, if options_tabulate contains missing then I need that one option here */ /* this is the purpose of this ex */ if `opt_missing_flag'==1 { qui tabulate `var1' `var2' if `touse',missing matrow(`m1') matcol(`m2') matcell(`m3') } else if `opt_missing_flag'==0 { qui tabulate `var1' `var2' if `touse',matrow(`m1') matcol(`m2') matcell(`m3') } /*matrix list `m1'*/ /*matrix list `m2'*/ /*matrix list `m3'*/ local valLabelA : value label `var1' /* row: value label name */ /*display `"value label name for `var1' is: `valLabelA'"'*/ /* display it */ local varLabelA : variable label `var1' /* row: variable label */ /*display `"variable label name for `var1' is: `varLabelA'"'*/ /* display it */ local valLabelB : value label `var2' /* col: value label name */ /*display `"value label name for `var2' is: `valLabelB'"'*/ /* display it */ local varLabelB : variable label `var2' /* col: variable label */ /*display `"variable label name for `var2' is: `varLabelB'"'*/ /* display it */ /* bgn by matrix */ tempname X tempname a tempname b tempname rX tempname mX tempname bX tempname aX tempname rXdim tempname otherrow tempvar rX1 tempvar rX2 tempvar rX3 tempvar rXdim_row matrix `X' = `m3' /* from matcell() option done quietly above */ local d_row = rowsof(`X') local d_col = colsof(`X') /* create the _a_ & _b_ vector */ matrix `a' = J(`d_row',1,0) matrix `b' = J(`d_row',1,1) /* 2 by col tables loop */ foreach l of numlist 1/`d_row' { matrix `a'[`l',1]=1 matrix `b'[`l',1]=0 matrix `aX' = `a''*`X' matrix `bX' = `b''*`X' /*matrix list `aX'*/ /*matrix list `bX'*/ matrix `mX' = `aX' \ `bX' /*matrix list `mX'*/ local rows = 2 * `d_col' matrix `rXdim'=J(`rows',1,0) qui svmat `rXdim' , names(`"`rXdim_row'"') foreach i of numlist 1/3 { qui gen `rX`i''=. } matrix `rX'=J(`rows',3,0) foreach i of numlist 1/2 { foreach j of numlist 1/`d_col' { local r_i=`d_col'*(`i'-1)+`j' qui replace `rX1'=`i' if _n==`r_i' qui replace `rX2'=`j' if _n==`r_i' qui replace `rX3'=`mX'[`i',`j'] if _n==`r_i' } } /*list `rX1' `rX2' `rX3' if `rXdim_row'==0*/ /* temp list variables for debug */ /* handle orginal row levels vs other rows */ if `m1'[`l',1] ~= . { local numeric_lvl = `m1'[`l',1] local lplusone=`numeric_lvl'+1 qui recode `rX1' 1=`numeric_lvl' 2=`lplusone' local missing_row_flag = 0 } else if `m1'[`l',1] == . { local numeric_lvl = `l' local lplusone=`numeric_lvl'+1 qui recode `rX1' 1=`l' 2=`lplusone' local missing_row_flag = 1 /*display `" here we are!! : missing_row_flag == `missing_row_flag' "'*/ } else { error 109 } /*list `rX1' `rX2' `rX3' if `rXdim_row'==0*/ /* temp list variables for debug */ if `"`valLabelA'"' ~= `""' { if `missing_row_flag'==0 { local valNameA : label `valLabelA' `numeric_lvl' /* row: value label for level `l', from natural levels */ display `"--> `valNameA' = : value level(`numeric_lvl')"' label define `otherrow' `numeric_lvl' `"`valNameA'"' `lplusone' `"all others"' } else { display `"--> _null_ = : value level(missing)"' label define `otherrow' `numeric_lvl' `"missing"' `lplusone' `"all others"' } label val `rX1' `otherrow' } else { if `missing_row_flag'==0 { display `"--> row `numeric_lvl' = : value level(`numeric_lvl')"' label define `otherrow' `numeric_lvl' `"row==`numeric_lvl'"' `lplusone' `"all others"' } else { display `"--> _null_ = : value level(missing)"' label define `otherrow' `numeric_lvl' `"missing"' `lplusone' `"all others"' } label val `rX1' `otherrow' } /* handle orginal column levels each time `rX2' is defined, once for each row value */ local recode_string = `""' if `"`valLabelB'"' ~= `""' { foreach j of numlist 1/`d_col' { if `m2'[1,`j'] ~= . { local numeric_col=`m2'[1,`j'] local recode_string = `"`recode_string' `j'=`numeric_col'"' local valNameB : label `valLabelB' `numeric_col' label define `rX2' `numeric_col' `"`valNameB'"',modify local prior_col_code = `numeric_col' /* keep prior code for potential missing as stata missing is last */ local missing_col_flag = 0 } else if `m2'[1,`j'] == . { local numeric_col=`prior_col_code'+1 local recode_string = `"`recode_string' `j'=`numeric_col'"' label define `rX2' `numeric_col' `"missing"',modify local missing_col_flag = 1 /*display `" here we are!! : missing_col_flag == `missing_col_flag' "'*/ } } } else { foreach j of numlist 1/`d_col' { if `m2'[1,`j'] ~= . { local numeric_col=`m2'[1,`j'] local recode_string = `"`recode_string' `j'=`numeric_col'"' label define `rX2' `numeric_col' `"col==`numeric_col'"',modify local prior_col_code = `numeric_col' /* keep prior code for potential missing as stata missing is last */ local missing_col_flag = 0 } else if `m2'[1,`j'] == . { local numeric_col=`prior_col_code'+1 local recode_string = `"`recode_string' `j'=`numeric_col'"' label define `rX2' `numeric_col' `"missing"',modify local missing_col_flag = 1 /*display `" here we are!! : missing_col_flag == `missing_col_flag' "'*/ } } } qui recode `rX2' `recode_string' /*if `"`valLabelB'"' ~= `""' {*/ label val `rX2' `rX2' /*}*/ /* handle row variable name */ if `"`varLabelA'"' ~= `""' { label var `rX1' `"`varLabelA'"' } else { label var `rX1' `"row"' } /* handle col variable name */ if `"`varLabelB'"' ~= `""' { label var `rX2' `"`varLabelB'"' } else { label var `rX2' `"col"' } /* do the tabulate command for each row */ if `"`rtabopts'"' == `""' { tabulate `rX1' `rX2' [freq=`rX3'] if `rXdim_row'==0 } else { tabulate `rX1' `rX2' [freq=`rX3'] if `rXdim_row'==0, `rtabopts' local exactp = r(p_exact) /* save the exact p*/ return scalar exactp`l' = `exactp' } display `""' label drop `otherrow' capture noi label drop `rX2' drop `rX1' `rX2' `rX3' `rXdim_row' /* reset the _a_ & _b_ vector */ matrix `a' = J(`d_row',1,0) matrix `b' = J(`d_row',1,1) } /* 2 by col tables loop */ matrix drop `X' `a' `b' `rX' `mX' `bX' `aX' `rXdim' /* end by matrix */ end /* tarow */