## Marginal Effects in Two-Part Fractional Models

As shown in “Two-Part Fractional Model” posted on 09/25/2012, sometimes it might be beneficial to model fractional outcomes in the range of [0, 1] with composite models, e.g. a two-part model, especially when there are a non-trivial number of boundary outcomes. However, the marginal effect of X in a two-part model is not as straightforward to calculate as in a one-part model shown in “Marginal Effects in Tobit Models” posted on 10/06/2012.

In the demonstration below, I will show how to calculate the marginal effect of X in a two-part model with a similar logic shown in McDonald and Moffitt decomposition.

proc nlmixed data = one tech = congra maxiter = 1000; parms b10 = -9.3586 b11 = -0.0595 b12 = 1.7644 b13 = 0.5994 b14 = -2.5496 b15 = -0.0007 b16 = -0.0011 b17 = -1.6359 b20 = 0.3401 b21 = 0.0274 b22 = 0.1437 b23 = 0.0229 b24 = 0.4656 b25 = 0.0011 b26 = 0.0021 b27 = 0.1977 s = 0.2149; logit_xb = b10 + b11 * x1 + b12 * x2 + b13 * x3 + b14 * x4 + b15 * x5 + b16 * x6 + b17 * x7; nls_xb = b20 + b21 * x1 + b22 * x2 + b23 * x3 + b24 * x4 + b25 * x5 + b26 * x6 + b27 * x7; p1 = 1 / (1 + exp(-logit_xb)); p2 = 1 / (1 + exp(-nls_xb)); if y = 0 then ll = log(1 - p1); else ll = log(p1) + log(pdf('normal', y, p2, s)); model y ~ general(ll); predict logit_xb out = out_1 (rename = (pred = part1_xb) keep = _id_ pred y); predict p1 out = out_2 (rename = (pred = part1_p) keep = _id_ pred); predict nls_xb out = out_3 (rename = (pred = part2_xb) keep = _id_ pred); predict p2 out = out_4 (rename = (pred = part2_p) keep = _id_ pred); run; data out; merge out_1 out_2 out_3 out_4; by _id_; margin1_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * -0.05948) * part2_p; margin1_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -0.01115) * part1_p; x1_margin = margin1_part1 + margin1_part2; margin2_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * 1.7645) * part2_p; margin2_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -0.4363) * part1_p; x2_margin = margin2_part1 + margin2_part2; margin3_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * 0.5994) * part2_p; margin3_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -0.1139) * part1_p; x3_margin = margin3_part1 + margin3_part2; margin4_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * -2.5496) * part2_p; margin4_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -2.8755) * part1_p; x4_margin = margin4_part1 + margin4_part2; margin5_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * -0.00071) * part2_p; margin5_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * 0.004091) * part1_p; x5_margin = margin5_part1 + margin5_part2; margin6_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * -0.00109) * part2_p; margin6_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -0.00839) * part1_p; x6_margin = margin6_part1 + margin6_part2; margin7_part1 = (exp(part1_xb) / ((1 + exp(part1_xb)) ** 2) * -1.6359) * part2_p; margin7_part2 = (exp(part2_xb) / ((1 + exp(part2_xb)) ** 2) * -0.1666) * part1_p; x7_margin = margin7_part1 + margin7_part2; run; proc means data = _last_ mean; var x:; run; /* Variable Mean x1_margin -0.0039520 x2_margin 0.0739847 x3_margin 0.0270673 x4_margin -0.3045967 x5_margin 0.000191015 x6_margin -0.000533998 x7_margin -0.1007960 */