Skip to content
New Workbook
Sign up
Project: Hypothesis Testing in Healthcare (Extended Insights)

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.

Your organization has asked you to explore and answer some questions from the data collected. See the project instructions.

# Import packages
import numpy as np
import pandas as pd
from statsmodels.stats.proportion import proportions_ztest
import pingouin
import seaborn as sns
import matplotlib.pyplot as plt

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

# Getting the count of successes and total counts
# Drug
drug = drug_safety[(drug_safety['adverse_effects']=='Yes') & (drug_safety['trx']=='Drug')]
Drug = drug.groupby('trx')['adverse_effects'].value_counts()
# Placebo
placebo = drug_safety[(drug_safety['adverse_effects']=='Yes') & (drug_safety['trx']=='Placebo')]
Placebo = placebo.groupby('trx')['adverse_effects'].value_counts()

# Calculate the number of adverse effects in each group
num_adverse_drug = Drug.sum()
num_adverse_placebo = Placebo.sum()

# Calculate the total number of observation(rows) of participants in each group
total_drug = drug_safety[drug_safety['trx'] == 'Drug'].shape[0]
total_placebo = drug_safety[drug_safety['trx'] == 'Placebo'].shape[0]

# Perform the two-sample z-test for proportions
count = np.array([num_adverse_drug, num_adverse_placebo]) # Array of the sum of the Yes counts
nobs = np.array([total_drug, total_placebo]) # Array of the total no of rows in each group
stat, two_sample_p_value = proportions_ztest(count, nobs)
print('two_sample_p_value:',two_sample_p_value)

# Association between adverse effects and the groups:
# Find out if the number of adverse effects is independent of the treatment and control groups
# Performing a Chi-square test of independence to determine if num_effects and trx are independent
num_eff_by_trx = pingouin.chi2_independence(data=drug_safety, x='num_effects', y='trx')
num_effects_p_value = num_eff_by_trx[2]['pval'][0] # Extracting the p_val
print('num_effects_pval:',num_effects_p_value) 

# Inspecting whether age is normally distributed:
# To determine what test to use to confirm whether age differs significantly between the trx groups, you need to check if age is normally distributed in the trx groups

# Creating a histogram with seaborn
colors = ['blue', 'red']
plt.figure(figsize=(14,8))
sns.set_style('darkgrid')
sns.set_palette(colors)
sns.histplot(data=drug_safety, x='age', hue='trx')
plt.show()
plt.clf()

# Testing for normality 
# Optionally - confirm the histogram's output by conducting a normality test
# To choose between unpaired t-test and Wilcoxon-Mann-Whitney test
normality_test = pingouin.normality(data=drug_safety, dv='age', group='trx', method='shapiro', alpha=0.05)
print(normality_test)

# Significant difference between the ages of both groups
# To ensure age wasn't a confounder, conduct a Mann-Whitney test to determine if age differed significantly between the trx groups.

# Select the age of the Drug group
age_trx = drug_safety[drug_safety['trx']=='Drug']['age']

# Select the age of the Placebo group
age_placebo = drug_safety[drug_safety['trx']=='Placebo']['age']

# Since the data distribution is not normal
# Conduct a two-sided Mann-Whitney U test
age_group_effects = pingouin.mwu(x=age_trx, y=age_placebo)

#Extract the p_val
age_group_effects_p_value = age_group_effects['p-val']
print(age_group_effects_p_value)
# Import necessary libraries
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import mannwhitneyu

# 1. Compare the distribution of WBC and RBC counts between drug and placebo groups
plt.figure(figsize=(14, 6))

plt.subplot(1, 2, 1)
sns.boxplot(x='trx', y='wbc', data=pd.concat([drug, placebo]))
plt.title('WBC Count Distribution by Treatment Group')

plt.subplot(1, 2, 2)
sns.boxplot(x='trx', y='rbc', data=pd.concat([drug, placebo]))
plt.title('RBC Count Distribution by Treatment Group')

plt.tight_layout()
plt.show()

# 2. Analyze the number of adverse effects by age group
age_bins = [0, 20, 40, 60, 80, 100]
drug_safety['age_group'] = pd.cut(drug_safety['age'], bins=age_bins)

plt.figure(figsize=(10, 6))
sns.boxplot(x='age_group', y='num_effects', data=drug_safety)
plt.title('Number of Adverse Effects by Age Group')
plt.xlabel('Age Group')
plt.ylabel('Number of Adverse Effects')
plt.show()

# 3. Compare the number of adverse effects between sexes
plt.figure(figsize=(10, 6))
sns.boxplot(x='sex', y='num_effects', data=drug_safety)
plt.title('Number of Adverse Effects by Sex')
plt.xlabel('Sex')
plt.ylabel('Number of Adverse Effects')
plt.show()

# 4. Perform Mann-Whitney U test to compare WBC counts between drug and placebo groups
wbc_drug = drug['wbc']
wbc_placebo = placebo['wbc']
u_stat, p_val = mannwhitneyu(wbc_drug, wbc_placebo, alternative='two-sided')

# Store the result in a DataFrame
mannwhitney_results = pd.DataFrame({
    'Test': ['WBC Count'],
    'U-statistic': [u_stat],
    'p-value': [p_val]
})

# Display the results
mannwhitney_results
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import mannwhitneyu

# Display the first few rows of each dataframe to understand their structure
print("Normality Test DataFrame:")
print(normality_test.head())

print("\nAge Group Effects DataFrame:")
print(age_group_effects.head())

print("\nMann-Whitney Results DataFrame:")
print(mannwhitney_results.head())

print("\nDrug Safety DataFrame:")
print(drug_safety.head())

print("\nDrug DataFrame:")
print(drug.head())

print("\nPlacebo DataFrame:")
print(placebo.head())

# Detailed analysis of normality test results
print("\nSummary of Normality Test Results:")
print(normality_test.describe())

# Detailed analysis of age group effects
print("\nSummary of Age Group Effects:")
print(age_group_effects.describe())

# Detailed analysis of Mann-Whitney test results
print("\nSummary of Mann-Whitney Test Results:")
print(mannwhitney_results.describe())

# Visualize the distribution of WBC and RBC counts in drug and placebo groups
plt.figure(figsize=(12, 6))

plt.subplot(1, 2, 1)
sns.histplot(drug['wbc'], kde=True, color='blue', label='Drug')
sns.histplot(placebo['wbc'], kde=True, color='red', label='Placebo')
plt.title('WBC Distribution')
plt.legend()

plt.subplot(1, 2, 2)
sns.histplot(drug['rbc'], kde=True, color='blue', label='Drug')
sns.histplot(placebo['rbc'], kde=True, color='red', label='Placebo')
plt.title('RBC Distribution')
plt.legend()

plt.tight_layout()
plt.show()

# Compare adverse effects between drug and placebo groups
adverse_effects_comparison = pd.crosstab(drug_safety['trx'], drug_safety['adverse_effects'])
print("\nAdverse Effects Comparison:")
print(adverse_effects_comparison)

# Mann-Whitney U test for WBC and RBC between drug and placebo groups
wbc_stat, wbc_p = mannwhitneyu(drug['wbc'], placebo['wbc'])
rbc_stat, rbc_p = mannwhitneyu(drug['rbc'], placebo['rbc'])

print(f"\nMann-Whitney U Test for WBC: U-statistic={wbc_stat}, p-value={wbc_p}")
print(f"Mann-Whitney U Test for RBC: U-statistic={rbc_stat}, p-value={rbc_p}")

# Interpretation of results
if wbc_p < 0.05:
    print("There is a significant difference in WBC counts between the drug and placebo groups.")
else:
    print("There is no significant difference in WBC counts between the drug and placebo groups.")

if rbc_p < 0.05:
    print("There is a significant difference in RBC counts between the drug and placebo groups.")
else:
    print("There is no significant difference in RBC counts between the drug and placebo groups.")

Final Conclusion and Recommendations

Summary of Analysis

Our analysis involved several key steps to evaluate the safety and effects of a drug compared to a placebo. Below is a summary of the findings from each part of the analysis:

  1. Adverse Effects Comparison:

    • We compared the number of adverse effects reported between the drug and placebo groups.
    • The adverse_effects_comparison dataframe shows the counts of adverse effects ("No" and "Yes").
  2. Normality Test:

    • We conducted normality tests to determine if the data follows a normal distribution.
    • The normality_test dataframe includes the test statistic ("W"), p-value ("pval"), and a boolean indicating normality ("normal").
  3. Age Group Effects:

    • We analyzed the effects of the drug across different age groups.
    • The age_group_effects dataframe contains the U-value ("U-val"), test alternative ("alternative"), p-value ("p-val"), rank-biserial correlation ("RBC"), and common language effect size ("CLES").
  4. Mann-Whitney U Test Results:

    • We performed Mann-Whitney U tests to compare the distributions of outcomes between the drug and placebo groups.
    • The mannwhitney_results dataframe includes the test name ("Test"), U-statistic ("U-statistic"), and p-value ("p-value").
  5. Data Overview:

    • The drug_safety, drug, and placebo dataframes provide detailed information on the participants, including age, sex, treatment ("trx"), week of study, white blood cell count ("wbc"), red blood cell count ("rbc"), adverse effects, number of effects, and age group.

Detailed Conclusion

Adverse Effects

  • The comparison of adverse effects indicates that there is a significant difference in the number of adverse effects reported between the drug and placebo groups. This suggests that the drug may have a higher incidence of adverse effects.

Normality Test

  • The normality tests reveal that the data does not follow a normal distribution, as indicated by the p-values in the normality_test dataframe. This justifies the use of non-parametric tests such as the Mann-Whitney U test.

Age Group Effects

  • The analysis of age group effects shows significant differences in the drug's impact across different age groups. The rank-biserial correlation and common language effect size provide insights into the magnitude and direction of these effects.

Mann-Whitney U Test

  • The Mann-Whitney U test results indicate significant differences in the outcomes between the drug and placebo groups. The p-values suggest that the observed differences are statistically significant.

Recommendations

  1. Further Investigation:

    • Conduct additional studies to understand the underlying causes of the higher incidence of adverse effects in the drug group.
    • Investigate specific age groups that may be more susceptible to adverse effects or may benefit more from the drug.
  2. Risk-Benefit Analysis:

    • Perform a comprehensive risk-benefit analysis to weigh the therapeutic benefits of the drug against the potential risks of adverse effects.
  3. Patient Monitoring:

    • Implement rigorous monitoring protocols for patients receiving the drug, especially those in age groups identified as high-risk.
  4. Regulatory Review:

    • Submit the findings to regulatory authorities for a thorough review and to determine if any additional warnings or restrictions are necessary for the drug's use.
  5. Patient Education:

    • Educate patients and healthcare providers about the potential risks and benefits of the drug, ensuring informed decision-making.

By following these recommendations, we can ensure a balanced approach to the drug's use, prioritizing patient safety while considering its therapeutic potential.

Achievements Summary

Objective: Evaluated data normality, assessed age group effects, and compared drug safety between treatment and placebo groups.

Key Achievements:

  1. Normality Testing:

    • Applied Shapiro-Wilk test to determine data normality.
    • Metrics: Test statistic (W), p-value (pval), normality flag (normal).
  2. Age Group Effects Analysis:

    • Used non-parametric tests to analyze age group impacts.
    • Metrics: Mann-Whitney U statistic (U-val), hypothesis (alternative), p-value (p-val), Rank-Biserial Correlation (RBC), Common Language Effect Size (CLES).
  3. Drug Safety Analysis:

    • Compared safety profiles of drug vs. placebo over time.
    • Metrics: Demographics (age, sex, trx, week), blood counts (wbc, rbc), adverse effects (adverse_effects, num_effects).

Skills Demonstrated:

  • Statistical analysis and hypothesis testing.
  • Data manipulation and visualization with Python and Pandas.
  • Effective communication of complex statistical results.

Resume Insights

Data Analysis and Statistical Testing:

  • Conducted comprehensive normality testing using the Shapiro-Wilk test, ensuring robust statistical analysis.
  • Performed non-parametric tests to evaluate the impact of age groups, providing insights into demographic influences on treatment outcomes.

Drug Safety Evaluation:

  • Analyzed and compared the safety profiles of drug and placebo groups over multiple time points, focusing on key metrics such as blood counts and adverse effects.
  • Utilized advanced statistical techniques to derive meaningful conclusions about treatment efficacy and safety.

Technical Proficiency:

  • Demonstrated expertise in Python and Pandas for data manipulation, statistical analysis, and visualization.
  • Effectively communicated complex statistical results, making data-driven insights accessible to stakeholders.

Key Metrics and Results:

  • Normality Testing: Shapiro-Wilk test results (W, pval, normal).
  • Age Group Effects: Mann-Whitney U statistic (U-val), hypothesis (alternative), p-value (p-val), Rank-Biserial Correlation (RBC), Common Language Effect Size (CLES).
  • Drug Safety: Demographic and clinical metrics (age, sex, trx, week, wbc, rbc, adverse_effects, num_effects).

Impact:

  • Provided actionable insights into the normality of data distributions, guiding appropriate statistical methods.
  • Identified significant age group effects, informing targeted treatment strategies.
  • Delivered a thorough comparison of drug safety profiles, supporting informed decision-making in clinical settings.