knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(BGrass) set.seed(1)
Our package aims to provide a Bayesian learning toolbox to detect vaccine safety signals while incorporating the AE network. Suppose we are comparing vaccine A with vaccine B on 10 adverse events (AEs). We assume the log odds ratio of the occurrence of AE j is $\beta_j$. In the following example, we have two groups of AEs, both of which are of size 5. In group 1, logORs are 0.5 for all AEs, while -0.5 for group 2. We assume we have another 5 isolated AEs (not in any groups) that have $\beta_j=0$.
J = 15 # number of AEs beta = rep(0,J) beta[1:5] = 0.5 beta[6:10] = -0.5
Suppose we have 2000 reports, and they either mention vaccine A or vaccine B, and we are adjusting for two columns of covariates. For different AEs, the covariates have different coefficients.
n = 2000 # number of reports V = rbinom(n, 1, 0.5) # indicator of vaccine A X = cbind(1, rbinom(n,1,0.5), rbinom(n,1,0.5)) # generating covariates Alpha = matrix(rnorm(3 * J), J, 3) # create coefficients for covariates
We generate the AE occurrence matrix A
using logistic link functions.
PA = X %*% t(Alpha) + V %*% t(beta) PA = 1 / (1 + exp(-PA)) A = rbinom(n * J, 1, PA) A = matrix(A, n, J)
We need to convert the AE groups into a Laplacian matrix. We provide a function getLaplacian
to simplify the task. The function takes a sequence of AEs, and a data frame of AE groups. The resulting matrix will have the order of rows and columns corresponding to the order of the input sequence.
data = data.frame(AE = c(paste0('AE', 1:10)), group = paste0('g', rep(1:2, each = 5))) L = getLaplacian(paste0('AE', 1:J), data)
Now, we can initialize the MCMC chain, update the chain, and use the coef
function to get the posterior means of the MCMC samples. We have an epsilon
that controls the strength of information borrowing. The smaller epsilon
is, the stronger the information borrowing, and when epsilon
is infinity, the model does not do any information borrowing and thus estimates AEs independently.
BGrass_chain1 = new_BGrass_chain(A, V, X, L, epsilon = Inf, n_thin = 2) BGrass_chain1 = update(BGrass_chain1, n_ite = 1000)
BGrass_chain2 = new_BGrass_chain(A, V, X, L, epsilon = 0.01, n_thin = 2) BGrass_chain2 = update(BGrass_chain2, n_ite = 1000)
Our model provides an indicator delta
that indicates vaccine signals, i.e., logOR's that are not equal to 0. Clearly, both models can successfully identify signals and noises.
delta_hat1 = coef(BGrass_chain1)$delta delta_hat2 = coef(BGrass_chain2)$delta delta_hat1 delta_hat2
We can use the MSE of $\hat{\beta} to compare the difference choices of epsilon
. Because we have intentionally designed the logORs in the same group to be identical, so epsilon = 0.001
works better than epsilon = Inf
as expected.
beta_hat1 = coef(BGrass_chain1)$beta_marginalized beta_hat2 = coef(BGrass_chain2)$beta_marginalized mean((beta-beta_hat1)^2) mean((beta-beta_hat2)^2)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.