Usage Examples for MDDC in R

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Introduction

This vignette contains various examples that illustrate usage of MDDC.

Installation

The MDDC package is available on CRAN and can be installed using the following code. Additionally, the development version can be found on GitHub.

install.packages("MDDC")

We load the MDDC package using the following line:

library(MDDC)

Dataset

We have included an adverse event dataset curated from FDA Adverse Event Reporting System (FAERS) called statin49 dataset which we will be using for describing the functionalities of MDDC. statin49 was downloaded and processed from the FAERS database, covering the period from the third quarter of 2014 (Q3 2014) to the fourth quarter of 2020 (Q4 2020). This dataset is a $50\times 7$ contingency table. The first 49 rows represent 49 important adverse events (AEs) associated with the statin class, while the final row aggregates the remaining 5,990 AEs.

The dataset statin49_AE_idx lists the cluster index of each AE in the statin49 dataset. The 49 AEs are classified into three clusters: 1) AEs associated with signs and symptoms of muscle injury, 2) AEs associated with laboratory tests for muscle injury, and 3) AEs associated with kidney injury and its laboratory diagnosis and treatment.

data("statin49")
head(statin49)

data("statin49_AE_idx")
head(statin49_AE_idx)

Adverse Event (AE) Identification with MDDC

Using Boxplot Method

Our goal is to identify (AE, drug) pairs with abnormally high report counts, specifically those cells with counts significantly exceeding their expected values.

First we perform the analysis using mddc_boxplot(). This function has five argument:

We now perform the MDDC (boxplot) analysis with the statin49 dataset:

set.seed(42)
test1 <- mddc_boxplot(
  contin_table = statin49,
  col_specific_cutoff = T,
  separate = T,
  if_col_cor = F,
  cor_lim = 0.8,
  coef = 1.5
)

The above function outputs a list with three components:

Below, we display the first few rows and columns for each component of test1. We first check the component boxplot_signal:

head(test1$boxplot_signal)[, 1:5]

This indicates the pairs (Rhabdomyolysis, Atorvastatin), (Rhabdomyolysis, Pravastatin), (Muscle Rupture, Pravastatin), (Rhabdomyolysis, Rosuvastatin), and (Muscle Disorder, Rosuvastatin) are identified as signals in step 2 of MDDC (boxplot). Now we look at the second component corr_signal_pval which shows the p-values of all the cells from step 5:

round(head(test1$corr_signal_pval)[, 1:5], digits = 3)

In this output, we observe that the first row, corresponding to the adverse event "Rhabdomyolysis", does not have associated p-values. This is because, in step 2 of the algorithm, "Rhabdomyolysis" was already identified as an AE signal for Atorvastatin, Pravastatin, Rosuvastatin, and Simvastatin. Consequently, the standardized Pearson residual values for these four drugs were replaced with NA. With only two residual values remaining in the first row, it was not possible to find connected AEs for "Rhabdomyolysis". Therefore, this adverse event was excluded from the subsequent steps of the analysis. Note that for computing the Pearson correlation in step 3, at least three values are required in the matching positions. Applying a p-value threshold of 0.05, we identify the following pairs as signals by considering AE correlations: (Muscle Rupture, Fluvastatin), (Muscle Rupture, Pravastatin), and (Muscle Disorder, Rosuvastatin).

The third component, corr_signal_adj_pval, provides the Benjamini-Hochberg adjusted p-values. Users can choose whether to use corr_signal_pval or corr_signal_adj_pval and can set their own p-value threshold (for example, 0.05).

Function for Finding Optimal Boxplot Coefficient

We provide a function that outputs appropriate coefficients for boxplot using a grid search method to control the FDR. This function takes the following arguments:

We apply this function to the statin49 dataset:

set.seed(42)
find_optimal_coef(
  contin_table = statin49,
  n_sim = 1000,
  target_fdr = 0.05,
  grid = 0.1,
  col_specific_cutoff = TRUE,
  exclude_small_count = TRUE
)

This function outputs a list with the following components:

Using the Monte Carlo Method

Next, we introduce another primary function of this package, mddc_mc(), which implements the MDDC (MC) algorithm. This function has the following arguments:

We now apply MDDC (MC) algorithm to statin49 using the following code:

set.seed(42)
test2 <- mddc_mc(
  contin_table = statin49,
  quantile = 0.95,
  rep = 10000,
  exclude_same_drug_class = T,
  col_specific_cutoff = T,
  separate = T,
  if_col_cor = F,
  cor_lim = 0.8
)

This function outputs a list with five components:

Function for Reporting

This package includes a postprocessing function report_drug_AE_pairs() for display the identified (AE, drug) pairs as well as the observed count, expected count and the standardized Pearson residuals for the pairs. This function takes two arguments:

Now we apply this function to the second component mc_signal we obtained above and display the first few rows:

test3 <- report_drug_AE_pairs(
  contin_table = statin49,
  contin_table_signal = test2$mc_signal
)

head(test3)

These (AE, drug) pairs are part of the signals identified by the MDDC (MC) method in step 2 for pairs with counts greater than five. Similarly, we can apply this function to the signals obtained from the correlation steps using the following code. Here we use a threshold of 0.05 for selecting the signals from step 5. We omit the output for brevity.

report_drug_AE_pairs(
  contin_table = statin49,
  contin_table_signal = test2$corr_signal_pval < 0.05
)

Simulating datasets with grouped AEs

This package offers a data generation function for simulating pharmacovigilance datasets, with the option to incorporate grouped AEs. This function can embed correlations between the standardized Pearson residuals for AEs and takes the following arguments:

Now we demonstrate the usage of this function by generating three simulated datasets based on the marginals of statin49. First, we need to create a data matrix with the same dimensions as statin49 that indicates the signal strength for each (AE, drug) pair. In this example, we assign a signal (Rhabdomyolysis, Atorvastatin) with a strength of 4 to the simulated dataset:

# create a matrix indicating signal strength
sig_mat <- matrix(1,
  nrow = nrow(statin49),
  ncol = ncol(statin49)
)

# assign (Rhabdomyolysis, Atorvastain) as a signal
# with a signal strength 4
sig_mat[1, 1] <- 4

The 49 AEs in statin49 can be grouped into three clusters, as listed in the statin49_AE_idx: 1) AEs associated with signs and symptoms of muscle injury, 2) AEs associated with laboratory tests for muscle injury, 3) AEs associated with kidney injury and its laboratory diagnosis and treatment. Next we take a look at the first few rows of sttain49_AE_idx, which indicate the group index of each AE in statin49:

head(statin49_AE_idx)

Now we generate 3 simulated contingency tables based on the marginals of statin49, the pre-specified matrix of signal strength, and the AE group index, with a within group correlation $\rho=0.5$:

sim_dat <- generate_contin_table_with_clustered_AE(
  contin_table = statin49,
  n_rep = 3,
  AE_idx = statin49_AE_idx,
  rho = 0.5,
  signal_mat = sig_mat,
  seed = 42
)

This function returns a list of simulated contingency tables, with the length of the list equal to the number of replications specified in the argument n_rep. In this example, we have n_rep = 3. Now we perform the MDDC (MC) analysis on the first simulated contingency table and extract the identified pairs from step 2:

test5 <- mddc_mc(sim_dat[[1]], seed = 42)
report_drug_AE_pairs(
  contin_table = sim_dat[[1]],
  contin_table_signal = test5$mc_signal
)

In the output, there is the pair (Rhabdomyolysis, Atorvastatin) identified, which matches what we embedded.

Visualization

We have also included heatmap visualizations as a part of our package to help visualize the identified signals or p-values.

This function takes the following arguments:

The following heatmap shows the visualization of the associated p-values of Monte Carlo method in step 2:

plot_heatmap(test2$mc_pval[-50, -7])


Try the MDDC package in your browser

Any scripts or data that you put into this service are public.

MDDC documentation built on April 11, 2025, 5:45 p.m.