Skip to content

Hypothesis Testing in Healthcare: Drug Safety

A pharmaceutical company GlobalXYZ has just completed a randomized controlled drug trial. To promote transparency and reproducibility of the drug's outcome, they (GlobalXYZ) have presented the dataset to your organization, a non-profit that focuses primarily on drug safety.

The dataset provided contained five adverse effects, demographic data, vital signs, etc. Your organization is primarily interested in the drug's adverse reactions. It wants to know if the adverse reactions, if any, are of significant proportions. It has asked you to explore and answer some questions from the data.

The dataset drug_safety.csv was obtained from Hbiostat courtesy of the Vanderbilt University Department of Biostatistics. It contained five adverse effects: headache, abdominal pain, dyspepsia, upper respiratory infection, chronic obstructive airway disease (COAD), demographic data, vital signs, lab measures, etc. The ratio of drug observations to placebo observations is 2 to 1.

For this project, the dataset has been modified to reflect the presence and absence of adverse effects adverse_effects and the number of adverse effects in a single individual num_effects.

The columns in the modified dataset are:

ColumnDescription
sexThe gender of the individual
ageThe age of the individual
weekThe week of the drug testing
trxThe treatment (Drug) and control (Placebo) groups
wbcThe count of white blood cells
rbcThe count of red blood cells
adverse_effectsThe presence of at least a single adverse effect
num_effectsThe number of adverse effects experienced by a single individual

The original dataset can be found here

# Import packages
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Load the dataset
drug_safety = pd.read_csv("drug_safety.csv")

sns.set_style('whitegrid')
plot_num_eff = sns.countplot(data=drug_safety, 
              x='num_effects', 
              hue='trx',
            palette="tab10")

# plot_num_eff.set_xlabel('Number of Adverse Effects')

for container in plot_num_eff.containers:
    plot_num_eff.bar_label(container)
    
plt.title("Distribution of the Number of Effects Between the Groups", y=1.03)
plt.xlabel("Number of Adverse Effects")

plt.show()
df1 = drug_safety.groupby("trx").agg(num_individuals=("trx", "count")).reset_index()
df1["proportion"] = df1["num_individuals"] / df1["num_individuals"].sum()
print(df1.head())

# Total individuals in trial
total_obs = drug_safety.trx.count()
print("\nTotal individuals in trial - {}\n".format(total_obs))

# put each group's total number of rows in a list [Drug, Placebo]

num_group_observed = df1["num_individuals"].tolist()
print(num_group_observed)
df2 = drug_safety.groupby(["trx", "adverse_effects"]).size().reset_index(name="count")
print(df2)
# Put the number of successes in each group in a list.
num_successes = df2[df2["adverse_effects"]=="Yes"]["count"].tolist()
num_successes

Conduct a two-sample Z-test to determine if the proportion of adverse effects differs significantly between the Drug and Placebo groups.
Save the resulting z statistic as a variable called two_samp_z_stat, and the p-value as a variable called two_samp_z_p_value, both of which rounded to three decimal places.

# Performing a two-sample proportion z test

from statsmodels.stats.proportion import proportions_ztest

zscore, pval = proportions_ztest(num_successes, num_group_observed, alternative="two-sided")
two_samp_z_stat = round(zscore, 3)
two_samp_z_p_value = round(pval, 3)

print("\nZ statistic is {}".format(two_samp_z_stat))
print("P-value is {}".format(two_samp_z_p_value))

Create histograms to visualize the distribution of age in the Drug and Placebo groups.

Performing a Chi-square test of independence

import pingouin

expected, observed, stats = pingouin.chi2_independence(data=drug_safety, \
                                                x="trx", y="num_effects", \
                                                      correction=False)
pearson_num_effect_trx = stats[stats['test'] == 'pearson'].round(3)
print(pearson_num_effect_trx)

Use the distributions to choose an appropriate statistical test that allows you to determine if there is a significant difference between the ages of the Drug and Placebo groups.

# Determine if there is a significant difference between the ages of the Drug and Placebo groups. 

sea = sns.FacetGrid(drug_safety,
                    col="trx",
                    height=4, 
                    aspect=1)
 
sea.map(sns.histplot, "age", stat="proportion", binwidth=2)
sea.fig.subplots_adjust(top=0.8) # adjust the Figure in rp
sea.fig.suptitle('Distribution of age in the groups', fontsize=16)
sea.set_axis_labels("Age (years)", "Proportions in groups")

plt.show()

Conduct a two-sided independent-samples t-test to determine if age differs significantly between the trx group

x = drug_safety.loc[drug_safety["trx"] == "Drug", "age"]
y = drug_safety.loc[drug_safety["trx"] == "Placebo", "age"]

# stats = pingouin.ttest(x, y)
# two_ind_samp_results = round(stats['p-val'], 3)
# two_ind_samp_results 

Performing Mann-Whitney U test.