*! version 1.0.1 PR 31oct2012 program define xfracpoly, eclass local VV : di "version " string(_caller()) ":" version 11.0 local cmdline : copy local 0 mata: _parse_colon("hascolon", "rhscmd") // _parse_colon() is stored in _parse_colon.mo if (`hascolon') { `VV' newfracpoly `"`0'"' `"`rhscmd'"' } else { `VV' xfracpoly_10 `0' } // ereturn cmdline overwrites e(cmdline) from fracpoly_10 ereturn local cmdline `"fracpoly `cmdline'"' end program define newfracpoly local VV : di "version " string(_caller()) ":" version 11.0 args 0 statacmd // Extract fracpoly options syntax, [*] local fracpolyopts `options' /* It is important that the fracpoly options precede the Stata command options. To ensure this, must extract the Stata options and reconstruct the command before presenting it to fracpoly_10. */ local 0 `statacmd' syntax [anything] [if] [in] [aw fw pw iw], [*] if `"`weight'"' != "" local wgt [`weight'`exp'] `VV' xfracpoly_10 `anything' `if' `in' `wgt', `fracpolyopts' `options' end program define xfracpoly_10, eclass local VV : di "version " string(_caller()) ":" version 11.0 if replay() { `VV' xfrac_154 `0' di as txt "Deviance:" as res %9.2f e(fp_dev) as txt "." exit } if !(_caller() < 12) { quietly ssd query if (r(isSSD)) { di as err "fracpoly not possible with summary statistic data" exit 111 } } local cmdline : copy local 0 gettoken cmd 0 : 0 xfrac_chk `cmd' if `s(bad)' { di as err "invalid or unrecognized command, `cmd'" exit 198 } local dist `s(dist)' syntax [anything(name=xlist)] [if] [in] [aw fw pw iw] [, * ] if `"`weight'"' != "" local wgt [`weight'`exp'] if `dist' != 7 { ChkDepvar lhs xlist : `"`xlist'"' if `dist' == 8 { local y1 `lhs' ChkDepvar y2 xlist : `"`xlist'"' local lhs `y1' `y2' } } if (`"`xlist'"'=="") { error 102 } local 0 `xlist' /* Look for predictors and associated powers */ local pwrs local rhs local nx 0 local lastnv 0 parse "`*'", parse(" ,[") gettoken next : 0, parse(" ,[") while "`next'"!= "" & "`next'"!="," & "`next'"!="if" & /* */ "`next'"!="in" & "`next'"!="[" { gettoken next 0 : 0, parse(" ,[") /* make real */ cap fvunab next : `next' if _rc == 0 { /* found a new xvarlist */ local varl `next' local nv : word count `varl' if `nx'>0 { /* have a previous xvarlist */ if "`pwrs'"=="" & `nx'>1 { local pwrs 1 } /* Flush powers */ local j=`nx'-`lastnv'+1 while `j'<=`nx' { local p`j' `pwrs' local j=`j'+1 } local pwrs } else { /* this is first xvarlist */ if `nv'>1 { di as err /* */ "`next' ambiguous---xvar [#] required before covariate model is specified" exit 198 } fvexpand `rhs' if "`r(fvops)'" == "true" { di as err "factor variables not allowed in this context" exit 198 } } /* Store current xvarlist names and update variable count */ forvalues j=1/`nv' { local ++nx local v`nx': word `j' of `varl' local rhs `rhs' `v`nx'' } local lastnv `nv' } else { /* got power(s) */ if `nx'==0 { di as err "invalid `next', not a varlist" exit 198 } CheckFVTS `next' cap confirm num `next' if _rc { di as err /// `""`next'" found where number or varlist expected"' exit 7 } local pwrs `pwrs' `next' } gettoken next : 0, parse(" ,[") } if `nx'==0 { di as err "no xvar found" exit 198 } /* Flush powers */ if "`pwrs'"=="" & `nx'>1 local pwrs 1 local j=`nx'-`lastnv'+1 while `j'<=`nx' { local p`j' `pwrs' local ++j } local 0 `"`lhs' `if' `in' `wgt', `options'"' if `dist' == 8 local vv varlist(min=2 max=2) else if `dist' != 7 local vv varname syntax `vv' [if] [in] [aw fw pw iw] [, /* */ ADjust(str) CENTer(str) ALL DEAD(varname) EXPx(str) ZERo(varlist) /* */ CATZero(varlist) ORIgin(str) REPort(numlist) noSCAling * ] if ("`adjust'"=="") { local adjust "`center'" } else if ("`center'"!="") { di as err "may not specify both adjust() and center()" exit 198 } tempvar touse mark `touse' [`weight' `exp'] `if' `in' if `dist' == 8 { quietly replace `touse' = 0 if `y1'>=. & `y2'>=. markout `touse' `rhs' `dead' `zero' `catzero' } else markout `touse' `lhs' `rhs' `dead' `zero' `catzero' /* With `all', estimation is restricted to `touse' subsample, but transformation is computed on all available values */ if "`all'"!="" { local restrict restrict(`touse') local fracgen_touse 1 } else local fracgen_touse `touse' frac_cox "`dead'" `dist' if "`dead'"!="" local dead dead(`dead') /* vars to be adjusted, taking number of unique values into account. */ xfrac_adj "`adjust'" "`rhs'" `touse' local i 0 while `i'<`nx' { local ++i local a `r(adj`i')' if "`a'"!="" { local adj`i'=cond(`i'==1, "`a'", "adjust(`a')" ) } } /* vars with expx option */ if "`expx'"!="" { xfrac_dis "`expx'" expx "`rhs'" local j 0 while `j'<`nx' { local ++j if "${S_`j'}"!="" { local exp`j' expx(${S_`j'}) } } } /* vars with origin option */ if "`origin'"!="" { xfrac_dis "`origin'" origin "`rhs'" local j 0 while `j'<`nx' { local ++j if "${S_`j'}"!="" { local ori`j' origin(${S_`j'}) } } } /* Vars with zero option */ if "`zero'"!="" { tokenize `zero' while "`1'"!="" { frac_in `1' "`rhs'" local zer`s(k)' "zero" mac shift } } /* Vars with catzero option */ if "`catzero'"!="" { tokenize `catzero' while "`1'"!="" { frac_in `1' "`rhs'" local cat`s(k)' "catzero" local zer`s(k)' "zero" /* catzero implies zero */ mac shift } } /* Construct fracpoly command to go to frac_154. First, remove old I* variables. */ forvalues i=1/`nx' { frac_mun `v`i'' purge } local base forvalues i=1/`nx' { local create= /* */ ("`p`i''"!="1" | "`zer`i''`ori`i''`exp`i''`adj`i''"!="") if `create' { /* garner unique name stub */ frac_mun `v`i'' local vn `s(name)' if `i'==1 { qui gen byte `vn'_1=. /*reserves name `vn'_1*/ local n name(`vn') /*force name in frac_154*/ } else { fracgen `v`i'' `p`i'' if `fracgen_touse', /* */ `restrict' sayesamp name(`vn') /* */ `adj`i'' `exp`i'' /* */ `zer`i'' `cat`i'' `ori`i'' `scaling' local base `base' `r(names)' local n`i' `r(names)' } } else { if `i'>1 { local base `base' `v`i'' local n`i' `v`i'' } } } if "`adj1'"=="" local adj adjust(no) else local adj adjust(`adj1') * Report effect sizes (differences on FP curve) at values in report. quietly if "`report'"!="" { local all all local nrep: word count `report' local n1=_N+1 local nplus=_N+`nrep' set obs `nplus' local j 1 forvalues i=`n1'/`nplus' { local X: word `j' of `report' replace `v1'=`X' in `i' local ++j } } `VV' /// xfrac_154 `cmd' `lhs' `v1' `p1' `base' if `fracgen_touse' [`weight' `exp'], /* */ `restrict' `n' `adj' `exp1' `zer1' `cat1' `ori1' `scaling' /* */ `dead' `options' version 10: ereturn local cmdline `"fracpoly `cmdline'"' * Compute effect sizes and SEs if "`report'"!="" { di as txt _n "{hline 17}{c TT}{hline 47}" /// _n %12s abbrev("`v1'", 16) /// _col(18)"{c |} Difference Std. Err. [$S_level% Conf. Interval]" /// _n "{hline 17}{c +}{hline 47}" tempname b V diff var se l u X Diff Se matrix `b'=e(b) matrix `V'=e(V) local nrow=`nrep'-1 matrix `X'=J(`nrow',2,0) matrix `Diff'=J(`nrow',1,0) matrix `Se'=J(`nrow',1,0) local catz=e(fp_catz) local m=wordcount("`e(fp_xp)'")-`catz' local tail=(1-$S_level/100)/2 if e(fp_dist)==0 local t=invttail(e(df_r),`tail') else local t=invnorm(1-`tail') * Store FP(x) values in first additional row local row=`nplus'-`nrep'+1 forvalues i=1/`m' { local I=`i'+`catz' local fpx: word `I' of `e(fp_xp)' tempname x1`i' x2`i' scalar `x1`i''=`fpx'[`row'] } local ++row local extra 1 // counts the points at which evaluation is required forvalues j=`row'/`nplus' { scalar `diff'=0 scalar `var'=0 forvalues i=1/`m' { local I=`i'+`catz' local fpx: word `I' of `e(fp_xp)' scalar `x2`i''=`fpx'[`j'] scalar `diff'=`diff'+`b'[1, `I']*(`x2`i''-`x1`i'') scalar `var'=`var'+`V'[`I', `I']*(`x2`i''-`x1`i'')^2 } if `m'>1 { forvalues i=1/`m' { local i1=`i'+1 local I=`i'+`catz' forvalues k=`i1'/`m' { local K=`k'+`catz' scalar `var'=`var'+2*`V'[`I', `K']* /// (`x2`i''-`x1`i'')*(`x2`k''-`x1`k'') } } } scalar `se'=sqrt(`var') scalar `l'=`diff'-`t'*`se' scalar `u'=`diff'+`t'*`se' local ix `extra' local X1: word `extra' of `report' local ++extra local X2: word `extra' of `report' matrix `X'[`ix',1]=`X1' matrix `X'[`ix',2]=`X2' matrix `Diff'[`ix',1]=`diff' matrix `Se'[`ix',1]=`se' di as text /* */ %8.0g `X1' "-" %-8.0g `X2' _col(18) "{c |}" /* */ _col(21) as res %9.0g `diff' /* */ _col(33) as res %9.0g `se' /* */ _col(47) %9.0g `l' /* */ _col(57) %9.0g `u' forvalues i=1/`m' { scalar `x1`i''=`x2`i'' } } di as txt "{hline 17}{c BT}{hline 47}" local row=`nplus'-`nrep'+1 qui drop in `row'/l ereturn matrix repx=`X' ereturn matrix repdiff=`Diff' ereturn matrix repse=`Se' } /* Store covariate names and their (fixed) powers, if any. Also, note presence of catzero variables in e(fp_c`i'). */ if e(fp_catz) ereturn local fp_c1 1 ereturn local fp_n1 `e(fp_xp)' forvalues i=2/`nx' { ereturn local fp_x`i' `v`i'' ereturn local fp_k`i' `p`i'' ereturn local fp_n`i' `n`i'' if "`cat`i''"!="" ereturn local fp_c`i' 1 } ereturn scalar fp_nx = `nx' end program CheckFVTS version 11 capture syntax [varlist(fv ts)] if c(rc) exit syntax varlist end program define ChkDepvar args dv xlist colon spec gettoken depvar spec : spec, parse(",") if (`"`depvar'"'=="") { error 102 } cap unab depvar : `depvar' gettoken depvar rest : depvar if _rc { unab depvar : `depvar' gettoken depvar rest2 : depvar } c_local `dv' `depvar' c_local `xlist' `rest2' `rest' `spec' end