Skip to content

Commit

Permalink
full vcov
Browse files Browse the repository at this point in the history
  • Loading branch information
anddis committed Jul 31, 2017
1 parent b268290 commit f9513c8
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 152 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# med4way
### A Stata command for the 4-way decomposition using parametric regression models

- Current version: `2.1.1`
- Release date: `28jul2017`
- Current version: `2.2.0`
- Release date: `31jul2017`

---

Expand Down
3 changes: 2 additions & 1 deletion med4way.ado
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
*! Hello, I'm med4way.ado
*! v2.1.1 - 28jul2017
*! v2.2.0 - 31jul2017

/*
Previous versions:
v2.1.1 - 28jul2017
v2.1.0 - 26jul2017
v2.0.0 - 27mar2017
*/
Expand Down
4 changes: 2 additions & 2 deletions med4way.pkg
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ d A.Discacciati, A.Bellavia, L.Valeri
d
d After installation, see help med4way
d
d Current version: 2.1.1
d Distribution-Date: 28jul2017
d Current version: 2.2.0
d Distribution-Date: 31jul2017
d
f med4way.ado
f med4way_engine.ado
Expand Down
22 changes: 16 additions & 6 deletions med4way.sthlp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{smcl}
{* *! version 2.1.1 28jul2017}{...}
{* *! version 2.2.0 31jul2017}{...}

{cmd:help med4way}
{hline}
Expand Down Expand Up @@ -90,9 +90,9 @@ Note: the 4-way decomposition holds without any assumptions about confounding. H
{p 7 6 2}{opt logb:inomial}: logbinomial regression (GLM with binomial distribution and log link function){p_end}
{p 7 6 2}{opt poi:sson}: Poisson regression{p_end}
{p 7 6 2}{opt negb:inomial}: negative binomial regression{p_end}
{p 7 6 2}{opt aft, {ul on}e{ul off}xponential}: Accelerated Failure Time (exponential survival distribution) ({cmd:stset} required){p_end}
{p 7 6 2}{opt aft, {ul on}w{ul off}eibull}: Accelerated Failure Time (Weibull survival distribution) ({cmd:stset} required){p_end}
{p 7 6 2}{opt cox}: Cox proportional hazards model ({cmd:stset} required){p_end}
{p 7 6 2}{opt aft, {ul on}e{ul off}xponential}: Accelerated Failure Time (exponential survival distribution) ({helpb stset} required){p_end}
{p 7 6 2}{opt aft, {ul on}w{ul off}eibull}: Accelerated Failure Time (Weibull survival distribution) ({helpb stset} required){p_end}
{p 7 6 2}{opt cox}: Cox proportional hazards model ({helpb stset} required){p_end}

{phang}
{opt mreg(string)} specifies the form of the regression model for the mediator. The available forms are:
Expand All @@ -108,7 +108,7 @@ Example: the covariates specified are {it:cvar1 cvar2 cvar3} and the user wants
{opt casec:ontrol} specifies that the data comes from a case-control study (that is, sampling was done on the outcome).

{phang}
{opt full:output} specifies that, in addition to to the 4 components of the total effect (controlled direct effect, reference interaction, mediated interaction, pure indirect effect), the following quantities are to be estimated: the proportions of the total effect due to each of the 4 components, the overall proportion mediated, the overall proportion due to interaction, and the overall proportion that would be eliminated if the mediator {it:mvar} were fixed to the value {opt m(#)}.
{opt full:output} specifies that, in addition to the 4 components of the total effect (controlled direct effect, reference interaction, mediated interaction, pure indirect effect), the following quantities are to be estimated: the proportions of the total effect due to each of the 4 components, the overall proportion mediated, the overall proportion due to interaction, and the overall proportion that would be eliminated if the mediator {it:mvar} were fixed to the value {opt m(#)}.

{phang}
{opt nodeltam:ethod} suppresses the calculation of the standard errors of the estimated quantities using the delta method.
Expand Down Expand Up @@ -164,8 +164,18 @@ See {help prefix_saving_option} for details about {it:suboptions}.
{pstd}Declare data to be survival-time data{p_end}
{phang2}{stata stset y_cens, failure(fail) noshow}

{pstd}Accelerated failure time regression model (exponential survival distribution) for the outcome; Logistic regression model for the mediator{p_end}
{phang2}{stata med4way treat m_bin cvar1, a0(0) a1(1) m(0) yreg(aft, e) mreg(logistic) c(1)}

{pstd}Test whether the excess relative risk due to controlled direct effect (ereri_cde) is statistically different from the excess relative risk due to pure indirect effect (ereri_pie){p_end}
{phang2}{stata test _b[ereri_cde] = _b[ereri_pie]}{p_end}

{pstd}Given the 4 basic components of the total effect, additional derived quantities can be estimated with the post-estimation commands {helpb lincom} or {helpb nlcom}, as appropriate.
For example, to calculate the overall proportion mediated (op_m){p_end}
{phang2}{stata nlcom (_b[ereri_pie]+_b[ereri_intmed])/(_b[ereri_cde]+_b[ereri_intref]+_b[ereri_intmed]+_b[ereri_pie]), noheader}{p_end}

{pstd}Accelerated failure time regression model (exponential survival distribution) for the outcome; Logistic regression model for the mediator; Display full output{p_end}
{phang2}{stata med4way treat m_bin cvar1, a0(0) a1(1) m(0) yreg(aft, e) mreg(logistic) c(1) fulloutput}
{phang2}{stata med4way treat m_bin cvar1, a0(0) a1(1) m(0) yreg(aft, e) mreg(logistic) c(1) fulloutput}{p_end}


{title:Stored results}
Expand Down
194 changes: 53 additions & 141 deletions med4way_engine.ado
Original file line number Diff line number Diff line change
Expand Up @@ -255,43 +255,25 @@ program define med4way_engine, eclass


********************************************************************************
*********** 4-way decomposition with delta method SE if needed *****************
*********** 4-way decomposition with delta method / bootstrap SE ***************
********************************************************************************
// Step 1===================================================================
// Prepare output empty matrices
tempname bEstimates VEstimates

matrix `bEstimates' = J(1, `nn', 0)
matrix `VEstimates' = J(`nn', `nn', 0)

matrix colnames `bEstimates' = `names'
matrix colnames `VEstimates' = `names'
matrix rownames `VEstimates' = `names'
//==========================================================================

// Step 2===================================================================
// Estimation: delta method or bootstrap
if (("`deltamethod'" == "true") & ("`bootstrap'" == "false")) {
foreach j of local names {
mata: m4w_deriv("`j'", st_matrix("`betay'"), st_matrix("`betam'"), /*
*/ st_matrix("`Vy'"), st_matrix("`Vm'"), /*
*/ st_matrix("`c'"), `nc', "`yreg'", "`mreg'", /*
*/ st_matrix("`aam'"), "false")
matrix `bEstimates'[1, colnumb(`bEstimates', "`j'")] = `p_estimate'
matrix `VEstimates'[colnumb(`VEstimates', "`j'"), /*
*/ rownumb(`VEstimates', "`j'")] = `dm_variance'
}
if (("`deltamethod'" == "false") & ("`bootstrap'" == "false")) {
matrix `bEstimates' = J(1, `nn', 0)
matrix `VEstimates' = J(`nn', `nn', 0)
}
else if (("`deltamethod'" == "false") & ("`bootstrap'" == "true")) {
foreach j of local names {
mata: m4w_deriv("`j'", st_matrix("`betay'"), st_matrix("`betam'"), /*
*/ st_matrix("`Vy'"), st_matrix("`Vm'"), /*
*/ st_matrix("`c'"), `nc', "`yreg'", "`mreg'", /*
*/ st_matrix("`aam'"), "true")
matrix `bEstimates'[1, colnumb(`bEstimates', "`j'")] = `p_estimate'
}
else {
mata: m4w_deriv(st_matrix("`betay'"), st_matrix("`betam'"), /*
*/ st_matrix("`Vy'"), st_matrix("`Vm'"), /*
*/ st_matrix("`c'"), `nc', "`yreg'", "`mreg'", /*
*/ st_matrix("`aam'"), "`bootstrap'", "`output'")
}
//==========================================================================

matrix colnames `bEstimates' = `names'
matrix colnames `VEstimates' = `names'
matrix rownames `VEstimates' = `names'
********************************************************************************

ereturn post `bEstimates' `VEstimates'
Expand Down Expand Up @@ -365,68 +347,59 @@ end regressml
* m4w_deriv (mata)
**********************/
clear mata
mata:
mata set matastrict on
set matastrict on

void function m4w_deriv(string scalar t, real vector betay, real vector betam, /*
mata:
void function m4w_deriv(real vector betay, real vector betam, /*
*/ real matrix Vy, real matrix Vm, real vector c, /*
*/ real scalar nc, string scalar yreg, string scalar mreg, /*
*/ real vector aam, string scalar boot) {
*/ real vector aam, string scalar boot, string scalar output) {
real vector b
real matrix V
real scalar p_estimate, dm_variance
pointer p
real vector b, p_estimates
real matrix V, dm_variance
transmorphic D, G
b = betay, betam
V = blockdiag(Vy, Vm)
p = findexternal("m4w_formulas()") // pointer!
D = deriv_init()
deriv_init_evaluator(D, &m4w_eval())
deriv_init_evaluator(D, &m4w_formulas())
deriv_init_evaluatortype(D, "t")
deriv_init_params(D, b)
deriv_init_argument(D, 1, p)
deriv_init_argument(D, 2, t)
deriv_init_argument(D, 3, c)
deriv_init_argument(D, 4, nc)
deriv_init_argument(D, 5, yreg)
deriv_init_argument(D, 6, mreg)
deriv_init_argument(D, 7, aam)
deriv_init_argument(D, 1, c)
deriv_init_argument(D, 2, nc)
deriv_init_argument(D, 3, yreg)
deriv_init_argument(D, 4, mreg)
deriv_init_argument(D, 5, aam)
deriv_init_argument(D, 6, output)
p_estimate = deriv(D, 0)
st_local("p_estimate", strofreal(p_estimate))
m4w_formulas(b, c, nc, yreg, mreg, aam, output, p_estimates) // point estimates
// note: it's much faster to call directly m4w_formulas than deriv(D, 0) to get p_estimates
if (boot == "false") {
G = deriv(D, 1)
dm_variance = (G*V*G')
st_local("dm_variance", strofreal(dm_variance))
dm_variance = G*V*G' // variance covariance matrix
}
}
/**********************
* m4w_eval (mata)
**********************/
void m4w_eval(real vector b, pointer(real scalar function) scalar f, /*
*/ string scalar t, real vector c, real scalar nc, /*
*/ string scalar yreg, string scalar mreg, real vector aam, v) {
v = (*f)(b, t, c, nc, yreg, mreg, aam)
else if (boot == "true") {
dm_variance = J(cols(p_estimates), cols(p_estimates), 0)
}
st_matrix(st_local("bEstimates"), p_estimates)
st_matrix(st_local("VEstimates"), dm_variance)
}
/**********************
* m4w_formulas (mata)
**********************/
real scalar m4w_formulas(real vector b, string scalar t, real vector c, /*
void m4w_formulas(real vector b, real vector c, /*
*/ real scalar nc, string scalar yreg, string scalar mreg, /*
*/ real vector aam) {
*/ real vector aam, string scalar output, v) {
real scalar offsetcox, i, betaTc, a0, a1, m, a1Ma0, a12Ma02, a1Tm, a0Tm, /*
real scalar offsetcox, betaTc, a0, a1, m, a1Ma0, a12Ma02, a1Tm, a0Tm, /*
*/ pie, intmed, intref, cde, A, B, te, ereri_cde, ereri_intref, /*
*/ ereri_intmed, ereri_pie, tereri
real vector theta, beta
real vector theta, beta, toreturn
//--------------theta------------------- | -------------beta----------------
Expand All @@ -444,7 +417,7 @@ real scalar m4w_formulas(real vector b, string scalar t, real vector c, /*
// split b into beta and theta - this makes the formulas below easier to read
// especially because after this offsetcox is not needed anymore
theta = b[|1 \ 4+nc+offsetcox|] // outcome model
beta = b[|5+nc+offsetcox \ cols(b)|] // mediator model
beta = b[|5+nc+offsetcox \ .|] // mediator model
if (nc>0) {
betaTc = beta[|2 \ nc+1|]*c' // linear combination covariates ("bcc" in vanderWeele)
Expand Down Expand Up @@ -481,41 +454,11 @@ real scalar m4w_formulas(real vector b, string scalar t, real vector c, /*
}
te = (cde + pie + intmed + intref)
if (t == "cde") {
return(cde)
}
if (t == "intref") {
return(intref)
}
if (t == "intmed") {
return(intmed)
}
if (t == "pie") {
return(pie)
}
if (t == "te") {
return(te)
}
if (t == "p_cde") {
return(cde/te)
}
if (t == "p_intref") {
return(intref/te)
}
if (t == "p_intmed") {
return(intmed/te)
}
if (t == "p_pie") {
return(pie/te)
}
if (t == "op_m") {
return((pie+intmed)/te)
}
if (t == "op_ati") {
return((intref+intmed)/te)
}
if (t == "op_e") {
return(1-(cde/te))
toreturn = (te, cde, intref, intmed, pie)
if (output=="full") {
// toreturn = te cde intref intmed pie p_cde p_intref p_intmed p_pie op_m op_ati op_e
// always check that this order agrees with the one of the local macro `names'
toreturn = (toreturn, cde/te, intref/te, intmed/te, pie/te, (pie+intmed)/te, (intref+intmed)/te, 1-(cde/te))
}
}
Expand Down Expand Up @@ -546,45 +489,14 @@ real scalar m4w_formulas(real vector b, string scalar t, real vector c, /*
tereri = ((exp(theta[1]*a1)*(1+exp(beta[nc+2]+beta[1]*a0+betaTc))*(1+exp(beta[nc+2]+beta[1]*a1+betaTc+theta[2]+theta[3]*a1))/(exp(theta[1]*a0)*(1+exp(beta[nc+2]+beta[1]*a1+betaTc))*(1+exp(beta[nc+2]+beta[1]*a0+betaTc+theta[2]+theta[3]*a0))))-1)
}
if (t == "ereri_cde") {
return(ereri_cde)
}
if (t == "ereri_intref") {
return(ereri_intref)
}
if (t == "ereri_intmed") {
return(ereri_intmed)
}
if (t == "ereri_pie") {
return(ereri_pie)
}
if (t == "tereri") {
return(tereri)
}
if (t == "terira") {
return((tereri+1))
}
if (t == "p_cde") {
return(ereri_cde/tereri)
}
if (t == "p_intref") {
return(ereri_intref/tereri)
}
if (t == "p_intmed") {
return(ereri_intmed/tereri)
}
if (t == "p_pie") {
return(ereri_pie/tereri)
}
if (t == "op_m") {
return((ereri_pie+ereri_intmed)/tereri)
}
if (t == "op_ati") {
return((ereri_intref+ereri_intmed)/tereri)
}
if (t == "op_e") {
return(1-(ereri_cde/tereri))
toreturn = (tereri, ereri_cde, ereri_intref, ereri_intmed, ereri_pie)
if (output=="full") {
// toreturn = tereri ereri_cde ereri_intref ereri_intmed ereri_pie terira p_cde p_intref p_intmed p_pie op_m op_ati op_e
// always check that this order agrees with the one of the local macro `names'
toreturn = (toreturn, (tereri+1), ereri_cde/tereri, ereri_intref/tereri, ereri_intmed/tereri, ereri_pie/tereri, (ereri_pie+ereri_intmed)/tereri, (ereri_intref+ereri_intmed)/tereri, 1-(ereri_cde/tereri))
}
}
v = toreturn
}
end mata
Binary file modified med4way_example_2.dta
Binary file not shown.

0 comments on commit f9513c8

Please sign in to comment.