Project 1 Data 110: Disease Death Counts vs Age Group

Project Overview

This project will explore how the specific diseases of Influenze, Pneumonia, and Covid-19 are correlated to each other within different age groups in the United States. This will allow more insight into how each of these diseases may affect each age group.

Data Source

This project will be using a dataset provided by the U.S. Department of Health & Human Services containing data of the provisional death counts for Influenza, Pneumonia, and Covid-19 across different regions of the country, different age groups, and in weekly intervals.

Variables

There are 17 variables and 50,400 observations within this dataset, of which include combinations of death counts, data on dates, jurisdiction, age group, and footnotes. 3 quantitative and 1 categorical variable will be used for this project. The 3 quantitative involve the death count for each of the 3 diseases, while the categorical variable will be the age group of the deceased being either 0-17 years, 18-64 years, and 65+ years old.

Loading Libraries

In order to loadthe dataset, create the visualization, and complete the correlation analysis I will be using the libraries for tidyverse and GGally.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(GGally)

Loading the Dataset

Use readr to load the dataset into variable “data”

data <- readr::read_csv("disease.csv")
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
Rows: 50400 Columns: 17
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (9): Data As Of, Start Week, End Week, Week Ending Date, Group, Indicato...
dbl (3): MMWRyear, MMWRweek, Influenza Deaths
num (5): COVID-19 Deaths, Total Deaths, Pneumonia Deaths, Pneumonia or Influ...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(data)
# A tibble: 6 × 17
  `Data As Of` `Start Week` `End Week` MMWRyear MMWRweek `Week Ending Date`
  <chr>        <chr>        <chr>         <dbl>    <dbl> <chr>             
1 11/02/2023   12/29/2019   01/04/2020     2020        1 01/04/2020        
2 11/02/2023   12/29/2019   01/04/2020     2020        1 01/04/2020        
3 11/02/2023   12/29/2019   01/04/2020     2020        1 01/04/2020        
4 11/02/2023   12/29/2019   01/04/2020     2020        1 01/04/2020        
5 11/02/2023   10/08/2023   10/14/2023     2023       41 10/14/2023        
6 11/02/2023   12/29/2019   01/04/2020     2020        1 01/04/2020        
# ℹ 11 more variables: Group <chr>, Indicator <chr>, Jurisdiction <chr>,
#   `Age Group` <chr>, `COVID-19 Deaths` <dbl>, `Total Deaths` <dbl>,
#   `Pneumonia Deaths` <dbl>, `Influenza Deaths` <dbl>,
#   `Pneumonia or Influenza` <dbl>,
#   `Pneumonia, Influenza, or COVID-19 Deaths` <dbl>, Footnote <chr>

Cleaning

#filtering NA values
t1 <- data |>
  filter(!is.na(`Age Group`) & !is.na(`COVID-19 Deaths`) & !is.na(`Pneumonia Deaths`) & !is.na(`Influenza Deaths`))
#narrows dataset to relevant columns
t2 <- t1 |>
  select(`Age Group`, `COVID-19 Deaths`, `Pneumonia Deaths`, `Influenza Deaths`)
t2
# A tibble: 24,745 × 4
   `Age Group`       `COVID-19 Deaths` `Pneumonia Deaths` `Influenza Deaths`
   <chr>                         <dbl>              <dbl>              <dbl>
 1 All Ages                          0               4102                432
 2 0-17 years                        0                 19                 22
 3 18-64 years                       0                767                183
 4 65 years and over                 0               3316                227
 5 0-17 years                        0                  0                  0
 6 0-17 years                        0                  0                  0
 7 0-17 years                        0                  0                  0
 8 0-17 years                        0                  0                  0
 9 All Ages                          0                465                 43
10 18-64 years                       0                 81                 18
# ℹ 24,735 more rows

Narrows down the dataset to the 4 variables this project will use, and filters out NA values to leave relevant data.

Visualization

A box plot will visualize how each of the disease death counts are affected by age group

#to visualize into a box plot, pivot_longer is needed to separate a plot for each disease type
long_t2 <- t2 |>
  pivot_longer(
    cols = c(`COVID-19 Deaths`, `Pneumonia Deaths`, `Influenza Deaths`),
    names_to = "Disease",
    values_to = "Deaths"
  )
#visualizing the box plots of death counts of each disease per age group
plot1 <- ggplot(long_t2, aes(x = `Age Group`, y = Deaths, fill = `Age Group`)) +
  geom_boxplot(alpha = 0.7) +
  scale_y_log10() +
  facet_wrap(~ Disease, scales = "free_y") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(
    title = "Disease Death Distributions Across Age Groups",
    x = "Age Group",
    y = "Death Count (log10 Scale)",
    caption = "Source: U.S. Department of Health & Human Services"
  )
plot1 + scale_fill_manual(values=c("0-17 years" = "#FFBBED", "18-64 years" = "#D3004C", "65 years and over" = "#5B2071", "All Ages" = "#12239E"))
Warning in scale_y_log10(): log-10 transformation introduced infinite values.
Warning: Removed 38917 rows containing non-finite outside the scale range
(`stat_boxplot()`).

The Covid-19 and Pneumonia box plots both show very similar distribution, while influenza is different especially in the 0-17 years old age range. However, all 3 plots show many high number outliers, indicating that for some weeks there were exceptionally high death counts among all 3 diseases and thus needing a log10 scale on the y axis to more easily show distribution.

Linear Regression

Thus because of the similarity in the Covid-19 and Pneumonia box plots, we can run a linear regression to see if there is any significant correlation.

fit1 <- lm(data = t2, `COVID-19 Deaths` ~ `Pneumonia Deaths`)
summary(fit1)

Call:
lm(formula = `COVID-19 Deaths` ~ `Pneumonia Deaths`, data = t2)

Residuals:
    Min      1Q  Median      3Q     Max 
-4853.5     9.8    38.2    38.5  6142.3 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)        -38.523083   2.039884  -18.89   <2e-16 ***
`Pneumonia Deaths`   1.182751   0.002525  468.50   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 313 on 24743 degrees of freedom
Multiple R-squared:  0.8987,    Adjusted R-squared:  0.8987 
F-statistic: 2.195e+05 on 1 and 24743 DF,  p-value: < 2.2e-16

The p-value for both variables are significant (less than 0.05), with both at < 2e-16.

The adjusted R-squared is 0.8984, which is a high correlation.

The equation for this model is y = 1.18x - 46.56, which in context means for each Covid-19 death, there is a predicted increase of 1.18 Pneumonia deaths.

plot(fit1) #diagnostic plots

The diagnostics heavily suggest that a linear model is not appropriate, as seen firstly by the first plot not being horizontal. And this is reasonable as explained in the box plot earlier, that since this data is about reported death counts, and many of these diseases caused high death tolls on specific weeks, needing a log10 scaling to properly show distribution. Having such a wide distribution makes it less likely that a linear regression model will be recommended. The QQPlot supports this, with the line not even close to being straight, and showing many outliers in the upper extremities. The Scale-Location plot also shows the effect of these outliers, causing the line to have a higher slope. And lastly, the Cook’s Distance plot shows a few outliers that have a very large leverage.

Conclusion

In conclusion, all 3 diseases have similar distributions of death counts among adult age groups (18-64 and 65+ age groups), but Covid-19 and Pneumonia show higher percentile of death counts for children (0-17 age group) than for influenza. However, although Covid-19 and Pneumonia show a high R-squared value and a p-value close to 0, the diagnostic plots show how a linear model is not quite fitting for data with such variance, such as death counts.

There were difficulties about trying to manage the columns (grammar) of the original dataset titles, but it has transferred well into the other plots. If I had more time, I would like to further go over relationships between other variables like region as well to possibly see how the diseases vary among them.