Youth Risk Behavior Surveillance

Youth Risk Behavior Surveillance

Every two years, the Centers for Disease Control and Prevention conduct the Youth Risk Behavior Surveillance System (YRBSS) survey, where it takes data from high schoolers (9th through 12th grade), to analyze health patterns.

Load the data

data(yrbss)
glimpse(yrbss)
## Rows: 13,583
## Columns: 13
## $ age                      <int> 14, 14, 15, 15, 15, 15, 15, 14, 15, 15, 15, 1…
## $ gender                   <chr> "female", "female", "female", "female", "fema…
## $ grade                    <chr> "9", "9", "9", "9", "9", "9", "9", "9", "9", …
## $ hispanic                 <chr> "not", "not", "hispanic", "not", "not", "not"…
## $ race                     <chr> "Black or African American", "Black or Africa…
## $ height                   <dbl> NA, NA, 1.73, 1.60, 1.50, 1.57, 1.65, 1.88, 1…
## $ weight                   <dbl> NA, NA, 84.4, 55.8, 46.7, 67.1, 131.5, 71.2, …
## $ helmet_12m               <chr> "never", "never", "never", "never", "did not …
## $ text_while_driving_30d   <chr> "0", NA, "30", "0", "did not drive", "did not…
## $ physically_active_7d     <int> 4, 2, 7, 0, 2, 1, 4, 4, 5, 0, 0, 0, 4, 7, 7, …
## $ hours_tv_per_school_day  <chr> "5+", "5+", "5+", "2", "3", "5+", "5+", "5+",…
## $ strength_training_7d     <int> 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 3, 0, 0, 7, 7, …
## $ school_night_hours_sleep <chr> "8", "6", "<5", "6", "9", "8", "9", "6", "<5"…

Exploratory Data Analysis on Weight

skim(yrbss) #count number of NAs in weight - 1004; summary statistics
(#tab:eda_on_weight)Data summary
Name yrbss
Number of rows 13583
Number of columns 13
_______________________
Column type frequency:
character 8
numeric 5
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
gender 12 1.00 4 6 0 2 0
grade 79 0.99 1 5 0 5 0
hispanic 231 0.98 3 8 0 2 0
race 2805 0.79 5 41 0 5 0
helmet_12m 311 0.98 5 12 0 6 0
text_while_driving_30d 918 0.93 1 13 0 8 0
hours_tv_per_school_day 338 0.98 1 12 0 7 0
school_night_hours_sleep 1248 0.91 1 3 0 7 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
age 77 0.99 16.16 1.26 12.00 15.0 16.00 17.00 18.00 ▁▂▅▅▇
height 1004 0.93 1.69 0.10 1.27 1.6 1.68 1.78 2.11 ▁▅▇▃▁
weight 1004 0.93 67.91 16.90 29.94 56.2 64.41 76.20 180.99 ▆▇▂▁▁
physically_active_7d 273 0.98 3.90 2.56 0.00 2.0 4.00 7.00 7.00 ▆▂▅▃▇
strength_training_7d 1176 0.91 2.95 2.58 0.00 0.0 3.00 5.00 7.00 ▇▂▅▂▅
yrbss %>%
  ggplot(aes(x = weight)) +
    geom_density() +
    theme_bw() +
    labs(title = "Distribution of Youth Weight",
         x = "Weight", 
         y = "Density")

# Youth weight looks relatively right-skewed, meaning that more youth are to the left of the weight distribution.

Relationship between weight and physical activity level

# Create indicator for activity level
yrbss <- yrbss %>%
  mutate(physical_3plus = ifelse(physically_active_7d >= 3, "yes", "no"))

#Count number of individuals active versus not active using count
count <- yrbss %>%
  count(physical_3plus) %>%
  mutate(percentage = n/sum(n) * 100)

count
## # A tibble: 3 × 3
##   physical_3plus     n percentage
##   <chr>          <int>      <dbl>
## 1 no              4404      32.4 
## 2 yes             8906      65.6 
## 3 <NA>             273       2.01
#Count number of individuals active versus not active using group_by & summarise
group_by <- yrbss %>%
  group_by(physical_3plus) %>%
  summarise(count = n()) %>%
  mutate(percentage = count/sum(count) * 100)

group_by
## # A tibble: 3 × 3
##   physical_3plus count percentage
##   <chr>          <int>      <dbl>
## 1 no              4404      32.4 
## 2 yes             8906      65.6 
## 3 <NA>             273       2.01
# There are almost half of individuals as active individuals who are less active. There is also NAs in level of activity in this dataset.

95% confidence interval - proportion of youth who are not active

prop.test(x = 4404, # number of high schoolers who exercise fewer than 3 days a week
          n = 13583, # number of total trials
          p = 0.5, #null hypothesis being that the proportion of population of activity levels equal 
          alternative = "two.sided", # two-tailed alternative hypothesis
          conf.level = 0.95, # 95% confidence internal assuming normal distribution
          correct = F)
## 
##  1-sample proportions test without continuity correction
## 
## data:  4404 out of 13583
## X-squared = 1679, df = 1, p-value <2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.316 0.332
## sample estimates:
##     p 
## 0.324
# Confidence interval = (0.316, 0.332)

Compare subgroup relationships between activity level and weight

yrbss %>%
  filter(!is.na(physical_3plus)) %>%
  ggplot(aes(x = physical_3plus, y = weight)) +
  geom_boxplot() +
  labs(title = "Boxplot of weights for different activity levels",
       x = "Activity level",
       y = "Weight") +
  NULL

# Graphically, the medians of these two variables don't look too different and the IQR either, implying that, weights do not differ depending on activity level. However, there are many outliers in both active and non-active groups. 

Confidence Intervals - 1-sample by level of activity

#Calculate summary statistics
ci_using_formulas <- yrbss %>%
  select(weight, physical_3plus) %>%
  filter(!is.na(physical_3plus)) %>%
  group_by(physical_3plus) %>%
  summarise(mean = mean(weight, na.rm = TRUE),
            sd = sd(weight, na.rm = TRUE),
            count = n(),
            se = sd / sqrt(count),
            t = qt(0.975, count-1),
            margin = t*se,
            l_ci = mean - margin,
            h_ci = mean + margin)

 ci_using_formulas 
## # A tibble: 2 × 9
##   physical_3plus  mean    sd count    se     t margin  l_ci  h_ci
##   <chr>          <dbl> <dbl> <int> <dbl> <dbl>  <dbl> <dbl> <dbl>
## 1 no              66.7  17.6  4404 0.266  1.96  0.521  66.2  67.2
## 2 yes             68.4  16.5  8906 0.175  1.96  0.342  68.1  68.8
# Confidence interval for not active: (66.2, 67.2)
# Confidence interval for active: (68.1, 68.8)

# The confidence intervals do not overlap, and the difference should be at least 95% statistically significant.

Difference in mean hypothesis test with formula & infer

Null hypothesis: mean weights are the same for those who exercise at least 3 times a week, and those who don’t Alternative hypothesis: mean weights are different for those who exercise at least 3 times a week, and those who don’t

Test using formula:

t.test(weight ~ physical_3plus,
       alternative = "two.sided",
       conf.level = 0.95,
       data = yrbss)
## 
##  Welch Two Sample t-test
## 
## data:  weight by physical_3plus
## t = -5, df = 7479, p-value = 9e-08
## alternative hypothesis: true difference in means between group no and group yes is not equal to 0
## 95 percent confidence interval:
##  -2.42 -1.12
## sample estimates:
##  mean in group no mean in group yes 
##              66.7              68.4
# p-value very small, hence very statistically significant. We reject the null hypothesis and that there is evidence to show that there is difference in mean between those who exercise at least 3 times a week, and those who don't.

Testing using infer:

Initialise the test by calculating the means in this sample.

obs_diff <- yrbss %>%
  filter(!is.na(physical_3plus)) %>% # filter so that there are no NAs
  specify(weight ~ physical_3plus) %>%
  calculate(stat = "diff in means", order = c("yes", "no"))

obs_diff #1.77 difference in means in this sample
## Response: weight (numeric)
## Explanatory: physical_3plus (factor)
## # A tibble: 1 × 1
##    stat
##   <dbl>
## 1  1.77

Simulate the null hypothesis using infer

set.seed(1234)

null_dist <- yrbss %>%
  filter(!is.na(physical_3plus)) %>%
  # specify variables
  specify(weight ~ physical_3plus) %>%
  
  # assume independence, i.e, there is no difference
  hypothesize(null = "independence") %>%
  
  # generate 1000 reps, of type "permute"
  generate(reps = 1000, type = "permute") %>%
  
  # calculate statistic of difference, namely "diff in means"
  calculate(stat = "diff in means", order = c("yes", "no"))

Visualise and plot hypothesis testing:

ggplot(data = null_dist, aes(x = stat)) +
  geom_histogram()  

null_dist %>% visualize() +
  shade_p_value(obs_stat = obs_diff, direction = "two-sided")

null_dist %>%
  get_p_value(obs_stat = obs_diff, direction = "two_sided")
## # A tibble: 1 × 1
##   p_value
##     <dbl>
## 1       0