We illustrate the general workflow of the CMAverse package by a quick example. The general workflow is:
Plot the DAG of causal relationships using cmdag.
Estimate causal effects and make inferences using cmest.
Conduct sensitivity analysis for unmeasured confounding and measurement error using cmsens.
Firstly, let’s load the package.
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## Loading required package: mstate
## Loading required package: survival
## Loading required package: tidyr
Next, we simulate some data and plot the DAG. The simulated dataset contains a binary exposure, a binary mediator, a continuous mediator, a continuous outcome and two baseline confounders.
set.seed(1)
n <- 100
C1 <- rnorm(n, mean = 1, sd = 1)
C2 <- rbinom(n, 1, 0.6)
pa <- exp(0.2 - 0.5*C1 + 0.1*C2)/(1 + exp(0.2 - 0.5*C1 + 0.1*C2))
A <- rbinom(n, 1, pa)
pm <- exp(1 + 0.5*A - 1.5*C1 + 0.5*C2)/ (1 + exp(1 + 0.5*A - 1.5*C1 + 0.5*C2))
M1 <- rbinom(n, 1, pm)
M2 <- rnorm(n, 2 + 0.8*A - M1 + 0.5*C1 + 2*C2, 1)
Y <- rnorm(n, mean = 0.5 + 0.4*A + 0.5*M1 + 0.6*M2 + 0.3*A*M1 + 0.2*A*M2 - 0.3*C1 + 2*C2, sd = 1)
data <- data.frame(A, M1, M2, Y, C1, C2)The DAG can be plotted using cmdag.
cmdag(outcome = "Y", exposure = "A", mediator = c("M1", "M2"),
basec = c("C1", "C2"), postc = NULL, node = FALSE, text_col = "black")
Then, we estimate causal effects using cmest. We use the regression-based approach for illustration. The reference values for the exposure are set to be 0 and 1. The reference values for the two mediators are set to be 1.
est <- cmest(data = data, model = "rb", outcome = "Y", exposure = "A",
mediator = c("M1", "M2"), basec = c("C1", "C2"), EMint = TRUE,
mreg = list("logistic", "linear"), yreg = "linear",
astar = 0, a = 1, mval = list(1, 1),
estimation = "imputation", inference = "bootstrap", nboot = 20)Summarize and plot the results:
summary(est)## Causal Mediation Analysis
##
## # Outcome regression:
##
## Call:
## glm(formula = Y ~ A + M1 + M2 + A * M1 + A * M2 + C1 + C2, family = gaussian(),
## data = getCall(x$reg.output$yreg)$data, weights = getCall(x$reg.output$yreg)$weights)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.47763 -0.59177 0.03214 0.66470 1.92837
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.429317 0.446678 -0.961 0.3390
## A 1.305199 0.751816 1.736 0.0859 .
## M1 0.762169 0.310811 2.452 0.0161 *
## M2 0.691868 0.132038 5.240 1.01e-06 ***
## C1 -0.197350 0.136885 -1.442 0.1528
## C2 2.389790 0.355404 6.724 1.46e-09 ***
## A:M1 0.127853 0.466496 0.274 0.7846
## A:M2 -0.001608 0.151163 -0.011 0.9915
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for gaussian family taken to be 1.100923)
##
## Null deviance: 571.51 on 99 degrees of freedom
## Residual deviance: 101.28 on 92 degrees of freedom
## AIC: 303.06
##
## Number of Fisher Scoring iterations: 2
##
##
## # Mediator regressions:
##
## Call:
## glm(formula = M1 ~ A + C1 + C2, family = binomial(), data = getCall(x$reg.output$mreg[[1L]])$data,
## weights = getCall(x$reg.output$mreg[[1L]])$weights)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.9623 -0.9462 -0.4322 0.9679 2.2586
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.003446 0.547959 0.006 0.994982
## A 0.828694 0.456732 1.814 0.069616 .
## C1 -0.984454 0.292880 -3.361 0.000776 ***
## C2 0.892199 0.511832 1.743 0.081308 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 138.47 on 99 degrees of freedom
## Residual deviance: 115.67 on 96 degrees of freedom
## AIC: 123.67
##
## Number of Fisher Scoring iterations: 3
##
##
##
## Call:
## glm(formula = M2 ~ A + C1 + C2, family = gaussian(), data = getCall(x$reg.output$mreg[[2L]])$data,
## weights = getCall(x$reg.output$mreg[[2L]])$weights)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.60482 -0.60844 0.02378 0.58801 2.59561
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.6403 0.2564 6.397 5.75e-09 ***
## A 0.2901 0.2170 1.337 0.184
## C1 0.6208 0.1189 5.219 1.04e-06 ***
## C2 2.0833 0.2366 8.806 5.44e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for gaussian family taken to be 1.110528)
##
## Null deviance: 225.08 on 99 degrees of freedom
## Residual deviance: 106.61 on 96 degrees of freedom
## AIC: 300.19
##
## Number of Fisher Scoring iterations: 2
##
##
## # Effect decomposition on the mean difference scale via the regression-based approach
##
## Direct counterfactual imputation estimation with
## bootstrap standard errors, percentile confidence intervals and p-values
##
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 1.431445 0.406563 0.791552 2.177 <2e-16 ***
## pnde 1.345009 0.210568 1.034657 1.751 <2e-16 ***
## tnde 1.363720 0.222721 1.001818 1.727 <2e-16 ***
## pnie 0.315062 0.175113 0.012484 0.526 0.1 .
## tnie 0.333773 0.150220 0.011253 0.510 <2e-16 ***
## te 1.678782 0.282291 1.201192 2.157 <2e-16 ***
## intref -0.086436 0.340713 -0.716350 0.427 0.7
## intmed 0.018712 0.094136 -0.148749 0.177 1.0
## cde(prop) 0.852669 0.204465 0.517111 1.231 <2e-16 ***
## intref(prop) -0.051487 0.223188 -0.496311 0.279 0.7
## intmed(prop) 0.011146 0.054510 -0.083948 0.103 1.0
## pnie(prop) 0.187673 0.099768 0.009682 0.317 0.1 .
## pm 0.198819 0.084045 0.008982 0.292 <2e-16 ***
## int -0.040341 0.234302 -0.528828 0.273 0.7
## pe 0.147331 0.204465 -0.230814 0.483 0.6
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (cde: controlled direct effect; pnde: pure natural direct effect; tnde: total natural direct effect; pnie: pure natural indirect effect; tnie: total natural indirect effect; te: total effect; intref: reference interaction; intmed: mediated interaction; cde(prop): proportion cde; intref(prop): proportion intref; intmed(prop): proportion intmed; pnie(prop): proportion pnie; pm: overall proportion mediated; int: overall proportion attributable to interaction; pe: overall proportion eliminated)
##
## Relevant variable values:
## $a
## [1] 1
##
## $astar
## [1] 0
##
## $mval
## $mval[[1]]
## [1] 1
##
## $mval[[2]]
## [1] 1
ggcmest(est) +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 30, vjust = 0.8))
Lastly, we conduct sensitivity analysis for the results. Sensitivity analysis for unmeasured confounding:
cmsens(object = est, sens = "uc")## Sensitivity Analysis For Unmeasured Confounding
##
## Evalues on the risk or rate ratio scale:
## estRR lowerRR upperRR Evalue.estRR Evalue.lowerRR Evalue.upperRR
## cde 1.719704 1.2724617 2.324143 2.832214 1.861272 NA
## pnde 1.664318 1.4239257 1.945293 2.715810 2.200868 NA
## tnde 1.676154 1.4211994 1.976847 2.740738 2.194897 NA
## pnie 1.126739 0.9896507 1.282818 1.504631 1.000000 NA
## tnie 1.134753 1.0152410 1.268333 1.525791 1.139632 NA
## te 1.888589 1.5321886 2.327891 3.184035 2.435191 NA
Assume that \(C_1\) was measured with error. Sensitivity analysis for measurement error using regression calibration with a set of assumed error standard deviations 0.1, 0.2 and 0.3:
me1 <- cmsens(object = est, sens = "me", MEmethod = "rc",
MEvariable = "C1", MEvartype = "con", MEerror = c(0.1, 0.2, 0.3))Summarize and plot the results:
summary(me1)## Sensitivity Analysis For Measurement Error
##
## The variable measured with error: C1
## Type of the variable measured with error: continuous
##
## # Measurement error 1:
## [1] 0.1
##
## ## Error-corrected regressions for measurement error 1:
##
## ### Outcome regression:
## Call:
## rcreg(reg = getCall(x$sens[[1L]]$reg.output$yreg)$reg, formula = Y ~
## A + M1 + M2 + A * M1 + A * M2 + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$yreg)$data,
## MEvariable = "C1", MEerror = 0.1, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[1L]]$reg.output$yreg)$weights)
##
## Naive coefficient estimates:
## (Intercept) A M1 M2 C1 C2
## -0.429317055 1.305199111 0.762169424 0.691868043 -0.197349688 2.389790272
## A:M1 A:M2
## 0.127853354 -0.001607689
##
## Naive var-cov estimates:
## (Intercept) A M1 M2 C1
## (Intercept) 0.19952129 -0.186177297 -0.071800151 -0.042143887 -0.012473494
## A -0.18617730 0.565227608 0.061763824 0.035566831 0.008550886
## M1 -0.07180015 0.061763824 0.096603550 0.011127995 0.008367323
## M2 -0.04214389 0.035566831 0.011127995 0.017433949 -0.005541985
## C1 -0.01247349 0.008550886 0.008367323 -0.005541985 0.018737581
## C2 0.03202116 -0.002076496 -0.025485517 -0.031937394 0.011413789
## A:M1 0.05250394 -0.194186113 -0.081844376 0.001218548 -0.006350845
## A:M2 0.03868322 -0.102112096 -0.008061219 -0.010381316 -0.000334026
## C2 A:M1 A:M2
## (Intercept) 0.032021156 0.052503937 0.038683218
## A -0.002076496 -0.194186113 -0.102112096
## M1 -0.025485517 -0.081844376 -0.008061219
## M2 -0.031937394 0.001218548 -0.010381316
## C1 0.011413789 -0.006350845 -0.000334026
## C2 0.126311866 -0.027375016 0.006147880
## A:M1 -0.027375016 0.217618968 0.019236723
## A:M2 0.006147880 0.019236723 0.022850334
##
## Variable measured with error:
## C1
## Measurement error:
## 0.1
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.427276 0.491050 -0.870 0.3865
## A 1.304514 0.698672 1.867 0.0651 .
## M1 0.761089 0.367873 2.069 0.0414 *
## M2 0.692841 0.138823 4.991 2.83e-06 ***
## C1 -0.200697 0.125629 -1.598 0.1136
## C2 2.387891 0.403462 5.919 5.52e-08 ***
## A:M1 0.127853 0.419520 0.305 0.7612
## A:M2 -0.001608 0.146484 -0.011 0.9913
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## ### Mediator regressions:
## Call:
## rcreg(reg = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$reg,
## formula = M1 ~ A + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$data,
## MEvariable = "C1", MEerror = 0.1, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 0.003446339 0.828694328 -0.984453987 0.892199087
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.30025921 -0.07438249 -0.08381839 -0.17194314
## A -0.07438249 0.20860406 -0.00266003 -0.01458923
## C1 -0.08381839 -0.00266003 0.08577848 -0.01275232
## C2 -0.17194314 -0.01458923 -0.01275232 0.26197192
##
## Variable measured with error:
## C1
## Measurement error:
## 0.1
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01887 0.59405 0.032 0.9747
## A 0.82577 0.47531 1.737 0.0855 .
## C1 -0.99703 0.38187 -2.611 0.0105 *
## C2 0.89185 0.53795 1.658 0.1006
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## rcreg(reg = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$reg,
## formula = M2 ~ A + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$data,
## MEvariable = "C1", MEerror = 0.1, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 1.6402566 0.2901364 0.6208107 2.0833115
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.06573913 -0.018924346 -0.0173562931 -0.0381103530
## A -0.01892435 0.047073002 0.0032931500 -0.0062472874
## C1 -0.01735629 0.003293150 0.0141472682 0.0003964488
## C2 -0.03811035 -0.006247287 0.0003964488 0.0559647177
##
## Variable measured with error:
## C1
## Measurement error:
## 0.2
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5998 0.2463 6.494 3.68e-09 ***
## A 0.2978 0.2096 1.421 0.159
## C1 0.6538 0.1424 4.591 1.34e-05 ***
## C2 2.0842 0.1979 10.531 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## ## Error-corrected causal effects on the mean difference scale for measurement error 1:
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 1.43076 0.48404 0.50383 2.171 <2e-16 ***
## pnde 1.34817 0.20632 1.05104 1.791 <2e-16 ***
## tnde 1.37327 0.17717 1.08960 1.675 <2e-16 ***
## pnie 0.35452 0.18379 -0.01758 0.564 0.1 .
## tnie 0.37962 0.19266 -0.10602 0.565 0.2
## te 1.72779 0.24969 1.17260 1.972 <2e-16 ***
## intref -0.08259 0.43750 -0.63768 0.762 0.9
## intmed 0.02510 0.12151 -0.20516 0.206 0.8
## cde(prop) 0.82809 0.24952 0.32071 1.183 <2e-16 ***
## intref(prop) -0.04780 0.25965 -0.33667 0.481 0.9
## intmed(prop) 0.01453 0.07225 -0.12151 0.133 0.8
## pnie(prop) 0.20518 0.09714 -0.02255 0.294 0.1 .
## pm 0.21971 0.10895 -0.08306 0.297 0.2
## int -0.03327 0.27433 -0.35268 0.581 0.9
## pe 0.17191 0.24952 -0.18337 0.679 0.5
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ----------------------------------------------------------------
##
## # Measurement error 2:
## [1] 0.2
##
## ## Error-corrected regressions for measurement error 2:
##
## ### Outcome regression:
## Call:
## rcreg(reg = getCall(x$sens[[2L]]$reg.output$yreg)$reg, formula = Y ~
## A + M1 + M2 + A * M1 + A * M2 + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$yreg)$data,
## MEvariable = "C1", MEerror = 0.2, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[2L]]$reg.output$yreg)$weights)
##
## Naive coefficient estimates:
## (Intercept) A M1 M2 C1 C2
## -0.429317055 1.305199111 0.762169424 0.691868043 -0.197349688 2.389790272
## A:M1 A:M2
## 0.127853354 -0.001607689
##
## Naive var-cov estimates:
## (Intercept) A M1 M2 C1
## (Intercept) 0.19952129 -0.186177297 -0.071800151 -0.042143887 -0.012473494
## A -0.18617730 0.565227608 0.061763824 0.035566831 0.008550886
## M1 -0.07180015 0.061763824 0.096603550 0.011127995 0.008367323
## M2 -0.04214389 0.035566831 0.011127995 0.017433949 -0.005541985
## C1 -0.01247349 0.008550886 0.008367323 -0.005541985 0.018737581
## C2 0.03202116 -0.002076496 -0.025485517 -0.031937394 0.011413789
## A:M1 0.05250394 -0.194186113 -0.081844376 0.001218548 -0.006350845
## A:M2 0.03868322 -0.102112096 -0.008061219 -0.010381316 -0.000334026
## C2 A:M1 A:M2
## (Intercept) 0.032021156 0.052503937 0.038683218
## A -0.002076496 -0.194186113 -0.102112096
## M1 -0.025485517 -0.081844376 -0.008061219
## M2 -0.031937394 0.001218548 -0.010381316
## C1 0.011413789 -0.006350845 -0.000334026
## C2 0.126311866 -0.027375016 0.006147880
## A:M1 -0.027375016 0.217618968 0.019236723
## A:M2 0.006147880 0.019236723 0.022850334
##
## Variable measured with error:
## C1
## Measurement error:
## 0.2
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.420717 0.445340 -0.945 0.3473
## A 1.302311 0.686413 1.897 0.0609 .
## M1 0.757615 0.336763 2.250 0.0269 *
## M2 0.695971 0.141661 4.913 3.89e-06 ***
## C1 -0.211459 0.131371 -1.610 0.1109
## C2 2.381786 0.407953 5.838 7.85e-08 ***
## A:M1 0.127853 0.416065 0.307 0.7593
## A:M2 -0.001608 0.147519 -0.011 0.9913
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## ### Mediator regressions:
## Call:
## rcreg(reg = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$reg,
## formula = M1 ~ A + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$data,
## MEvariable = "C1", MEerror = 0.2, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 0.003446339 0.828694328 -0.984453987 0.892199087
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.30025921 -0.07438249 -0.08381839 -0.17194314
## A -0.07438249 0.20860406 -0.00266003 -0.01458923
## C1 -0.08381839 -0.00266003 0.08577848 -0.01275232
## C2 -0.17194314 -0.01458923 -0.01275232 0.26197192
##
## Variable measured with error:
## C1
## Measurement error:
## 0.1
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01887 0.59405 0.032 0.9747
## A 0.82577 0.47531 1.737 0.0855 .
## C1 -0.99703 0.38187 -2.611 0.0105 *
## C2 0.89185 0.53795 1.658 0.1006
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## rcreg(reg = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$reg,
## formula = M2 ~ A + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$data,
## MEvariable = "C1", MEerror = 0.2, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 1.6402566 0.2901364 0.6208107 2.0833115
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.06573913 -0.018924346 -0.0173562931 -0.0381103530
## A -0.01892435 0.047073002 0.0032931500 -0.0062472874
## C1 -0.01735629 0.003293150 0.0141472682 0.0003964488
## C2 -0.03811035 -0.006247287 0.0003964488 0.0559647177
##
## Variable measured with error:
## C1
## Measurement error:
## 0.2
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5998 0.2463 6.494 3.68e-09 ***
## A 0.2978 0.2096 1.421 0.159
## C1 0.6538 0.1424 4.591 1.34e-05 ***
## C2 2.0842 0.1979 10.531 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## ## Error-corrected causal effects on the mean difference scale for measurement error 2:
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 1.42856 0.44643 0.87142 2.265 <2e-16 ***
## pnde 1.34820 0.29883 1.02428 2.007 <2e-16 ***
## tnde 1.38608 0.23999 1.10216 1.852 <2e-16 ***
## pnie 0.43455 0.22837 -0.04455 0.762 0.2
## tnie 0.47243 0.22519 -0.02189 0.785 0.1 .
## te 1.82063 0.28524 1.29467 2.287 <2e-16 ***
## intref -0.08036 0.28911 -0.64895 0.353 0.8
## intmed 0.03788 0.11409 -0.25826 0.135 0.9
## cde(prop) 0.78465 0.20642 0.53497 1.197 <2e-16 ***
## intref(prop) -0.04414 0.17446 -0.36559 0.241 0.8
## intmed(prop) 0.02080 0.06157 -0.11798 0.085 0.9
## pnie(prop) 0.23868 0.11705 -0.03051 0.404 0.2
## pm 0.25949 0.12229 -0.01219 0.434 0.1 .
## int -0.02333 0.17994 -0.31283 0.241 0.6
## pe 0.21535 0.20642 -0.19714 0.465 0.5
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ----------------------------------------------------------------
##
## # Measurement error 3:
## [1] 0.3
##
## ## Error-corrected regressions for measurement error 3:
##
## ### Outcome regression:
## Call:
## rcreg(reg = getCall(x$sens[[3L]]$reg.output$yreg)$reg, formula = Y ~
## A + M1 + M2 + A * M1 + A * M2 + C1 + C2, data = getCall(x$sens[[3L]]$reg.output$yreg)$data,
## MEvariable = "C1", MEerror = 0.3, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[3L]]$reg.output$yreg)$weights)
##
## Naive coefficient estimates:
## (Intercept) A M1 M2 C1 C2
## -0.429317055 1.305199111 0.762169424 0.691868043 -0.197349688 2.389790272
## A:M1 A:M2
## 0.127853354 -0.001607689
##
## Naive var-cov estimates:
## (Intercept) A M1 M2 C1
## (Intercept) 0.19952129 -0.186177297 -0.071800151 -0.042143887 -0.012473494
## A -0.18617730 0.565227608 0.061763824 0.035566831 0.008550886
## M1 -0.07180015 0.061763824 0.096603550 0.011127995 0.008367323
## M2 -0.04214389 0.035566831 0.011127995 0.017433949 -0.005541985
## C1 -0.01247349 0.008550886 0.008367323 -0.005541985 0.018737581
## C2 0.03202116 -0.002076496 -0.025485517 -0.031937394 0.011413789
## A:M1 0.05250394 -0.194186113 -0.081844376 0.001218548 -0.006350845
## A:M2 0.03868322 -0.102112096 -0.008061219 -0.010381316 -0.000334026
## C2 A:M1 A:M2
## (Intercept) 0.032021156 0.052503937 0.038683218
## A -0.002076496 -0.194186113 -0.102112096
## M1 -0.025485517 -0.081844376 -0.008061219
## M2 -0.031937394 0.001218548 -0.010381316
## C1 0.011413789 -0.006350845 -0.000334026
## C2 0.126311866 -0.027375016 0.006147880
## A:M1 -0.027375016 0.217618968 0.019236723
## A:M2 0.006147880 0.019236723 0.022850334
##
## Variable measured with error:
## C1
## Measurement error:
## 0.3
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.408067 0.460020 -0.887 0.3774
## A 1.298063 0.763918 1.699 0.0927 .
## M1 0.750917 0.360103 2.085 0.0398 *
## M2 0.702005 0.144481 4.859 4.83e-06 ***
## C1 -0.232211 0.154111 -1.507 0.1353
## C2 2.370014 0.389731 6.081 2.69e-08 ***
## A:M1 0.127853 0.422092 0.303 0.7626
## A:M2 -0.001608 0.156159 -0.010 0.9918
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## ### Mediator regressions:
## Call:
## rcreg(reg = getCall(x$sens[[3L]]$reg.output$mreg[[1L]])$reg,
## formula = M1 ~ A + C1 + C2, data = getCall(x$sens[[3L]]$reg.output$mreg[[1L]])$data,
## MEvariable = "C1", MEerror = 0.3, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[3L]]$reg.output$mreg[[1L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 0.003446339 0.828694328 -0.984453987 0.892199087
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.30025921 -0.07438249 -0.08381839 -0.17194314
## A -0.07438249 0.20860406 -0.00266003 -0.01458923
## C1 -0.08381839 -0.00266003 0.08577848 -0.01275232
## C2 -0.17194314 -0.01458923 -0.01275232 0.26197192
##
## Variable measured with error:
## C1
## Measurement error:
## 0.1
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.01887 0.59405 0.032 0.9747
## A 0.82577 0.47531 1.737 0.0855 .
## C1 -0.99703 0.38187 -2.611 0.0105 *
## C2 0.89185 0.53795 1.658 0.1006
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## rcreg(reg = getCall(x$sens[[3L]]$reg.output$mreg[[2L]])$reg,
## formula = M2 ~ A + C1 + C2, data = getCall(x$sens[[3L]]$reg.output$mreg[[2L]])$data,
## MEvariable = "C1", MEerror = 0.3, variance = TRUE, nboot = 400,
## weights = getCall(x$sens[[3L]]$reg.output$mreg[[2L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 1.6402566 0.2901364 0.6208107 2.0833115
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.06573913 -0.018924346 -0.0173562931 -0.0381103530
## A -0.01892435 0.047073002 0.0032931500 -0.0062472874
## C1 -0.01735629 0.003293150 0.0141472682 0.0003964488
## C2 -0.03811035 -0.006247287 0.0003964488 0.0559647177
##
## Variable measured with error:
## C1
## Measurement error:
## 0.2
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5998 0.2463 6.494 3.68e-09 ***
## A 0.2978 0.2096 1.421 0.159
## C1 0.6538 0.1424 4.591 1.34e-05 ***
## C2 2.0842 0.1979 10.531 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## ## Error-corrected causal effects on the mean difference scale for measurement error 3:
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 1.424309 0.496395 0.649747 2.215 <2e-16 ***
## pnde 1.351906 0.194064 1.026094 1.698 <2e-16 ***
## tnde 1.359081 0.186556 1.043619 1.733 <2e-16 ***
## pnie 0.261721 0.178343 0.003803 0.622 0.1 .
## tnie 0.268896 0.180014 0.010873 0.597 0.1 .
## te 1.620802 0.271680 1.356412 2.205 <2e-16 ***
## intref -0.072403 0.399889 -0.517447 0.696 0.9
## intmed 0.007175 0.070969 -0.129360 0.105 1.0
## cde(prop) 0.878768 0.218673 0.438724 1.091 <2e-16 ***
## intref(prop) -0.044671 0.241895 -0.259947 0.487 0.9
## intmed(prop) 0.004427 0.038630 -0.068683 0.058 1.0
## pnie(prop) 0.161476 0.088226 -0.001076 0.306 0.1 .
## pm 0.165903 0.091571 0.003433 0.305 0.1 .
## int -0.040244 0.250874 -0.310818 0.468 0.9
## pe 0.121232 0.218673 -0.091012 0.561 0.5
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ----------------------------------------------------------------
##
## (cde: controlled direct effect; pnde: pure natural direct effect; tnde: total natural direct effect; pnie: pure natural indirect effect; tnie: total natural indirect effect; te: total effect; intref: reference interaction; intmed: mediated interaction; cde(prop): proportion cde; intref(prop): proportion intref; intmed(prop): proportion intmed; pnie(prop): proportion pnie; pm: overall proportion mediated; int: overall proportion attributable to interaction; pe: overall proportion eliminated)
##
## Relevant variable values:
## $a
## [1] 1
##
## $astar
## [1] 0
##
## $mval
## $mval[[1]]
## [1] 1
##
## $mval[[2]]
## [1] 1
ggcmsens(me1) +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 30, vjust = 0.8))
Then, assume that the exposure was measured with error. Sensitivity analysis for measurement error using SIMEX with two assumed misclassification matrices:
me2 <- cmsens(object = est, sens = "me", MEmethod = "simex", MEvariable = "A",
MEvartype = "cat", B = 5,
MEerror = list(matrix(c(0.95, 0.05, 0.05, 0.95), nrow = 2),
matrix(c(0.9, 0.1, 0.1, 0.9), nrow = 2)))Summarize and plot the results:
summary(me2)## Sensitivity Analysis For Measurement Error
##
## The variable measured with error: A
## Type of the variable measured with error: categorical
##
## # Measurement error 1:
## [,1] [,2]
## [1,] 0.95 0.05
## [2,] 0.05 0.95
##
## ## Error-corrected regressions for measurement error 1:
##
## ### Outcome regression:
## Call:
## simexreg(reg = getCall(x$sens[[1L]]$reg.output$yreg)$reg, formula = Y ~
## A + M1 + M2 + A * M1 + A * M2 + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$yreg)$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.95,
## 0.05, 0.05, 0.95), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[1L]]$reg.output$yreg)$weights)
##
## Naive coefficient estimates:
## (Intercept) A M1 M2 C1 C2
## -0.429317055 1.305199111 0.762169424 0.691868043 -0.197349688 2.389790272
## A:M1 A:M2
## 0.127853354 -0.001607689
##
## Naive var-cov estimates:
## (Intercept) A M1 M2 C1
## (Intercept) 0.19952129 -0.186177297 -0.071800151 -0.042143887 -0.012473494
## A -0.18617730 0.565227608 0.061763824 0.035566831 0.008550886
## M1 -0.07180015 0.061763824 0.096603550 0.011127995 0.008367323
## M2 -0.04214389 0.035566831 0.011127995 0.017433949 -0.005541985
## C1 -0.01247349 0.008550886 0.008367323 -0.005541985 0.018737581
## C2 0.03202116 -0.002076496 -0.025485517 -0.031937394 0.011413789
## A:M1 0.05250394 -0.194186113 -0.081844376 0.001218548 -0.006350845
## A:M2 0.03868322 -0.102112096 -0.008061219 -0.010381316 -0.000334026
## C2 A:M1 A:M2
## (Intercept) 0.032021156 0.052503937 0.038683218
## A -0.002076496 -0.194186113 -0.102112096
## M1 -0.025485517 -0.081844376 -0.008061219
## M2 -0.031937394 0.001218548 -0.010381316
## C1 0.011413789 -0.006350845 -0.000334026
## C2 0.126311866 -0.027375016 0.006147880
## A:M1 -0.027375016 0.217618968 0.019236723
## A:M2 0.006147880 0.019236723 0.022850334
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.95 0.05
## 1 0.05 0.95
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.3948 0.3482 -1.134 0.2599
## A 1.8740 NaN NaN NaN
## M1 0.4391 0.3052 1.439 0.1536
## M2 0.7125 0.1249 5.705 1.40e-07 ***
## C1 -0.2333 0.1151 -2.026 0.0456 *
## C2 2.3301 0.3604 6.465 4.77e-09 ***
## A:M1 0.5823 0.5425 1.073 0.2859
## A:M2 -0.1226 NaN NaN NaN
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## ### Mediator regressions:
## Call:
## simexreg(reg = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$reg,
## formula = M1 ~ A + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.95,
## 0.05, 0.05, 0.95), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[1L]]$reg.output$mreg[[1L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 0.003446339 0.828694328 -0.984453987 0.892199087
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.30025921 -0.07438249 -0.08381839 -0.17194314
## A -0.07438249 0.20860406 -0.00266003 -0.01458923
## C1 -0.08381839 -0.00266003 0.08577848 -0.01275232
## C2 -0.17194314 -0.01458923 -0.01275232 0.26197192
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.95 0.05
## 1 0.05 0.95
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.1671 0.5520 0.303 0.7628
## A1 0.6279 0.5216 1.204 0.2317
## C1 -0.9362 0.2899 -3.230 0.0017 **
## C2 0.7649 0.5134 1.490 0.1396
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## simexreg(reg = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$reg,
## formula = M2 ~ A + C1 + C2, data = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.95,
## 0.05, 0.05, 0.95), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[1L]]$reg.output$mreg[[2L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 1.6402566 0.2901364 0.6208107 2.0833115
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.06573913 -0.018924346 -0.0173562931 -0.0381103530
## A -0.01892435 0.047073002 0.0032931500 -0.0062472874
## C1 -0.01735629 0.003293150 0.0141472682 0.0003964488
## C2 -0.03811035 -0.006247287 0.0003964488 0.0559647177
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.9 0.1
## 1 0.1 0.9
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5985 0.2803 5.702 1.30e-07 ***
## A 0.3403 0.3206 1.062 0.291
## C1 0.6341 0.1211 5.235 9.71e-07 ***
## C2 2.0890 0.2390 8.741 7.49e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## ## Error-corrected causal effects on the mean difference scale for measurement error 1:
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 2.333749 0.849479 0.392715 3.134 <2e-16 ***
## pnde 1.663306 0.231381 1.264425 2.003 <2e-16 ***
## tnde 1.675689 0.215797 1.364257 2.187 <2e-16 ***
## pnie 0.195664 0.229201 -0.069716 0.751 0.2
## tnie 0.208046 0.198643 0.081955 0.788 <2e-16 ***
## te 1.871352 0.264569 1.473680 2.360 <2e-16 ***
## intref -0.670443 0.732911 -1.404194 1.088 0.8
## intmed 0.012383 0.197096 -0.314801 0.398 0.9
## cde(prop) 1.247092 0.401435 0.198257 1.535 <2e-16 ***
## intref(prop) -0.358267 0.366638 -0.672400 0.549 0.8
## intmed(prop) 0.006617 0.092040 -0.135806 0.189 0.9
## pnie(prop) 0.104557 0.101725 -0.035695 0.322 0.2
## pm 0.111174 0.088811 0.048394 0.365 <2e-16 ***
## int -0.351650 0.381562 -0.557131 0.686 0.8
## pe -0.247092 0.401435 -0.535386 0.802 0.8
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ----------------------------------------------------------------
##
## # Measurement error 2:
## [,1] [,2]
## [1,] 0.9 0.1
## [2,] 0.1 0.9
##
## ## Error-corrected regressions for measurement error 2:
##
## ### Outcome regression:
## Call:
## simexreg(reg = getCall(x$sens[[2L]]$reg.output$yreg)$reg, formula = Y ~
## A + M1 + M2 + A * M1 + A * M2 + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$yreg)$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.9,
## 0.1, 0.1, 0.9), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[2L]]$reg.output$yreg)$weights)
##
## Naive coefficient estimates:
## (Intercept) A M1 M2 C1 C2
## -0.429317055 1.305199111 0.762169424 0.691868043 -0.197349688 2.389790272
## A:M1 A:M2
## 0.127853354 -0.001607689
##
## Naive var-cov estimates:
## (Intercept) A M1 M2 C1
## (Intercept) 0.19952129 -0.186177297 -0.071800151 -0.042143887 -0.012473494
## A -0.18617730 0.565227608 0.061763824 0.035566831 0.008550886
## M1 -0.07180015 0.061763824 0.096603550 0.011127995 0.008367323
## M2 -0.04214389 0.035566831 0.011127995 0.017433949 -0.005541985
## C1 -0.01247349 0.008550886 0.008367323 -0.005541985 0.018737581
## C2 0.03202116 -0.002076496 -0.025485517 -0.031937394 0.011413789
## A:M1 0.05250394 -0.194186113 -0.081844376 0.001218548 -0.006350845
## A:M2 0.03868322 -0.102112096 -0.008061219 -0.010381316 -0.000334026
## C2 A:M1 A:M2
## (Intercept) 0.032021156 0.052503937 0.038683218
## A -0.002076496 -0.194186113 -0.102112096
## M1 -0.025485517 -0.081844376 -0.008061219
## M2 -0.031937394 0.001218548 -0.010381316
## C1 0.011413789 -0.006350845 -0.000334026
## C2 0.126311866 -0.027375016 0.006147880
## A:M1 -0.027375016 0.217618968 0.019236723
## A:M2 0.006147880 0.019236723 0.022850334
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.9 0.1
## 1 0.1 0.9
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.19219 0.33891 -0.567 0.5720
## A 1.77271 0.77710 2.281 0.0248 *
## M1 0.55598 0.41379 1.344 0.1824
## M2 0.51478 0.11915 4.320 3.93e-05 ***
## C1 -0.08903 0.11618 -0.766 0.4455
## C2 2.62126 0.31421 8.342 6.96e-13 ***
## A:M1 -0.19204 0.65071 -0.295 0.7686
## A:M2 0.09880 0.17026 0.580 0.5631
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## ### Mediator regressions:
## Call:
## simexreg(reg = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$reg,
## formula = M1 ~ A + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.9,
## 0.1, 0.1, 0.9), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[2L]]$reg.output$mreg[[1L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 0.003446339 0.828694328 -0.984453987 0.892199087
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.30025921 -0.07438249 -0.08381839 -0.17194314
## A -0.07438249 0.20860406 -0.00266003 -0.01458923
## C1 -0.08381839 -0.00266003 0.08577848 -0.01275232
## C2 -0.17194314 -0.01458923 -0.01275232 0.26197192
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.95 0.05
## 1 0.05 0.95
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.1671 0.5520 0.303 0.7628
## A1 0.6279 0.5216 1.204 0.2317
## C1 -0.9362 0.2899 -3.230 0.0017 **
## C2 0.7649 0.5134 1.490 0.1396
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## simexreg(reg = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$reg,
## formula = M2 ~ A + C1 + C2, data = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$data,
## MEvariable = "A", MEvartype = "categorical", MEerror = c(0.9,
## 0.1, 0.1, 0.9), variance = TRUE, lambda = c(0.5, 1, 1.5,
## 2), B = 5, weights = getCall(x$sens[[2L]]$reg.output$mreg[[2L]])$weights)
##
## Naive coefficient estimates:
## (Intercept) A C1 C2
## 1.6402566 0.2901364 0.6208107 2.0833115
##
## Naive var-cov estimates:
## (Intercept) A C1 C2
## (Intercept) 0.06573913 -0.018924346 -0.0173562931 -0.0381103530
## A -0.01892435 0.047073002 0.0032931500 -0.0062472874
## C1 -0.01735629 0.003293150 0.0141472682 0.0003964488
## C2 -0.03811035 -0.006247287 0.0003964488 0.0559647177
##
## Variable measured with error:
## A
## Measurement error:
## 0 1
## 0 0.9 0.1
## 1 0.1 0.9
##
## Error-corrected results:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.5985 0.2803 5.702 1.30e-07 ***
## A 0.3403 0.3206 1.062 0.291
## C1 0.6341 0.1211 5.235 9.71e-07 ***
## C2 2.0890 0.2390 8.741 7.49e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## ## Error-corrected causal effects on the mean difference scale for measurement error 2:
## Estimate Std.error 95% CIL 95% CIU P.val
## cde 1.67947 1.08720 0.32807 3.399 <2e-16 ***
## pnde 2.07886 0.49879 1.11599 2.970 <2e-16 ***
## tnde 2.05103 0.31573 1.19583 2.285 <2e-16 ***
## pnie 0.35310 0.25901 0.01610 0.934 0.1 .
## tnie 0.32527 0.30363 -0.45864 0.565 0.2
## te 2.40413 0.32522 1.55424 2.596 <2e-16 ***
## intref 0.39939 0.77596 -1.24944 1.353 0.7
## intmed -0.02783 0.34260 -0.89762 0.274 0.9
## cde(prop) 0.69858 0.42020 0.18019 1.376 <2e-16 ***
## intref(prop) 0.16613 0.37337 -0.52542 0.653 0.7
## intmed(prop) -0.01158 0.14877 -0.37550 0.135 0.9
## pnie(prop) 0.14687 0.10723 0.01021 0.384 0.1 .
## pm 0.13530 0.14201 -0.18833 0.303 0.2
## int 0.15455 0.47312 -0.71832 0.719 0.9
## pe 0.30142 0.42020 -0.37555 0.820 0.7
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ----------------------------------------------------------------
##
## (cde: controlled direct effect; pnde: pure natural direct effect; tnde: total natural direct effect; pnie: pure natural indirect effect; tnie: total natural indirect effect; te: total effect; intref: reference interaction; intmed: mediated interaction; cde(prop): proportion cde; intref(prop): proportion intref; intmed(prop): proportion intmed; pnie(prop): proportion pnie; pm: overall proportion mediated; int: overall proportion attributable to interaction; pe: overall proportion eliminated)
##
## Relevant variable values:
## $a
## [1] 1
##
## $astar
## [1] 0
##
## $mval
## $mval[[1]]
## [1] 1
##
## $mval[[2]]
## [1] 1
ggcmsens(me2) +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 30, vjust = 0.8))