In this lab we will review exploratory data analysis using the ggplot2 package for data visualization, which is included in the tidyverse. The main focus of this lab is to be able to obtain and interpret credible intervals and hypothesis tests using Bayesian methods for numerical variables. The data and functions for inference can be found in the companion package for this course, statsr.
Let’s load the necessary packages for this week’s lab:
library(PairedData)
library(tidyverse)
library(statsr)
In 2004, the state of North Carolina released a large data set containing information on births recorded in this state. This data set is useful to researchers studying the relation between habits and practices of expectant mothers and the birth of their children. We will work with a random sample of observations from this data set.
Let’s load the nc data set into our workspace from the statsr package.
data(nc)
We have observations on 13 different variables, some categorical and some numerical. The meaning of each variable is as follows.
| variable | description |
|---|---|
fage |
father’s age in years. |
mage |
mother’s age in years. |
mature |
maturity status of mother. |
weeks |
length of pregnancy in weeks. |
premie |
whether the birth was classified as premature (premie) or full-term. |
visits |
number of hospital visits during pregnancy. |
marital |
whether mother is married or not married at birth. |
gained |
weight gained by mother during pregnancy in pounds. |
weight |
weight of the baby at birth in pounds. |
lowbirthweight |
whether baby was classified as low birthweight (low) or not (not low). |
gender |
gender of the baby, female or male. |
habit |
status of the mother as a nonsmoker or a smoker. |
whitemom |
whether mom is white or not white. |
Note: These data should be familiar for those who took the Inferential Statistics course as part of the Statistics with R specialization, where the nc data were used in the Inference for Numerical Data lab.
As a first step in the analysis, let’s take a look at the variables in the dataset and how R has encoded them. The most straight forward way of doing this is using the glimpse function.
glimpse(nc)
## Rows: 1,000
## Columns: 13
## $ fage <int> NA, NA, 19, 21, NA, NA, 18, 17, NA, 20, 30, NA, NA, NA…
## $ mage <int> 13, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16…
## $ mature <fct> younger mom, younger mom, younger mom, younger mom, yo…
## $ weeks <int> 39, 42, 37, 41, 39, 38, 37, 35, 38, 37, 45, 42, 40, 38…
## $ premie <fct> full term, full term, full term, full term, full term,…
## $ visits <int> 10, 15, 11, 6, 9, 19, 12, 5, 9, 13, 9, 8, 4, 12, 15, 7…
## $ marital <fct> married, married, married, married, married, married, …
## $ gained <int> 38, 20, 38, 34, 27, 22, 76, 15, NA, 52, 28, 34, 12, 30…
## $ weight <dbl> 7.63, 7.88, 6.63, 8.00, 6.38, 5.38, 8.44, 4.69, 8.81, …
## $ lowbirthweight <fct> not low, not low, not low, not low, not low, low, not …
## $ gender <fct> male, male, female, male, female, male, male, male, ma…
## $ habit <fct> nonsmoker, nonsmoker, nonsmoker, nonsmoker, nonsmoker,…
## $ whitemom <fct> not white, not white, white, white, not white, not whi…
Another useful function is summary which provides the range, quartiles, and means for numeric variables and counts for categorical variables. Additionally, if there are any missing observations (denoted NA), summary will provide the number of missing cases for each variable. Note that the output of the summary function can be too long and difficult to parse visually and interpret if the dataset has a large number of variables.
summary(nc)
## fage mage mature weeks premie
## Min. :14.00 Min. :13 mature mom :133 Min. :20.00 full term:846
## 1st Qu.:25.00 1st Qu.:22 younger mom:867 1st Qu.:37.00 premie :152
## Median :30.00 Median :27 Median :39.00 NA's : 2
## Mean :30.26 Mean :27 Mean :38.33
## 3rd Qu.:35.00 3rd Qu.:32 3rd Qu.:40.00
## Max. :55.00 Max. :50 Max. :45.00
## NA's :171 NA's :2
## visits marital gained weight
## Min. : 0.0 married :386 Min. : 0.00 Min. : 1.000
## 1st Qu.:10.0 not married:613 1st Qu.:20.00 1st Qu.: 6.380
## Median :12.0 NA's : 1 Median :30.00 Median : 7.310
## Mean :12.1 Mean :30.33 Mean : 7.101
## 3rd Qu.:15.0 3rd Qu.:38.00 3rd Qu.: 8.060
## Max. :30.0 Max. :85.00 Max. :11.750
## NA's :9 NA's :27
## lowbirthweight gender habit whitemom
## low :111 female:503 nonsmoker:873 not white:284
## not low:889 male :497 smoker :126 white :714
## NA's : 1 NA's : 2
##
##
##
##
As you review the variable summaries, consider which variables are categorical and which are numerical. For numerical variables, are there outliers? If you aren’t sure or want to take a closer look at the data, you can make a graph.
For example, we can examine the distribution of the amount of weight that a mother gained with a histogram.
ggplot(data = nc, aes(x = gained)) +
geom_histogram(binwidth = 5)
## Warning: Removed 27 rows containing non-finite values (stat_bin).
This function says to plot the gained variable from the nc data frame on the x-axis. It also defines a geom (short for geometric object), which describes the type of plot you will produce. We used a binwidth of 5, however you can change this value and see how it affects the shape of the histogram. Also note that the function results in a warning saying that 27 rows have been removed. This is because 27 observations in the data have NA values for weight gained. You can confirm this by peeking back at the summary output above. If you need a refresher on using ggplot2, you may want to take some time to review the material in the earlier courses in this specialization.
How many of the 13 variables are categorical?
# Type your code for Question 1 here.
We will start with analyzing the weight of the babies at birth, which is contained in the variable weight.
Use a visualization such as a histogram and summary statistics tools in R to analyze the distribution of weight. Which of the following best describes the distribution of weight?
# Type your code for Question 2 here.
ggplot(data = nc, aes(x = weight)) +
geom_histogram(binwidth = .5)
The variable premie in the dataframe classifies births on whether they were full-term or premie. We can use some of the functions of dplyr to create a new dataframe to limit the analysis to full term births.
nc_fullterm = filter(nc, premie == 'full term')
summary(nc_fullterm)
## fage mage mature weeks premie
## Min. :14.00 Min. :13 mature mom :109 Min. :37.00 full term:846
## 1st Qu.:25.00 1st Qu.:22 younger mom:737 1st Qu.:38.00 premie : 0
## Median :30.00 Median :27 Median :39.00
## Mean :30.24 Mean :27 Mean :39.25
## 3rd Qu.:35.00 3rd Qu.:32 3rd Qu.:40.00
## Max. :50.00 Max. :50 Max. :45.00
## NA's :132
## visits marital gained weight
## Min. : 0.00 married :312 Min. : 0.00 Min. : 3.750
## 1st Qu.:10.00 not married:534 1st Qu.:22.00 1st Qu.: 6.750
## Median :12.00 Median :30.00 Median : 7.440
## Mean :12.35 Mean :31.13 Mean : 7.459
## 3rd Qu.:15.00 3rd Qu.:40.00 3rd Qu.: 8.190
## Max. :30.00 Max. :85.00 Max. :11.750
## NA's :6 NA's :19
## lowbirthweight gender habit whitemom
## low : 30 female:431 nonsmoker:739 not white:228
## not low:816 male :415 smoker :107 white :616
## NA's : 2
##
##
##
##
The filter function selects variables all variables from the dataframe nc where the condition premie equals “full term” is met.
Repeat the visualization and summary with the weights from full term term births. Does weight appear to be approximately normally distributed?
Next we will introduce a function bayes_inference that we will use for constructing credible intervals and conducting hypothesis tests. The following illustrates how we would use the function bayes_inference to construct a 95% credible interval of weight; the Bayesian analogue to a 95% confidence interval.
bayes_inference(y = weight, data = nc_fullterm,
statistic = "mean", type = "ci",
prior_family = "JZS", mu_0 = 7.7, rscale = 1,
method = "simulation",
cred_level = 0.95)
## Single numerical variable
## n = 846, y-bar = 7.4594, s = 1.075
## (Assuming Zellner-Siow Cauchy prior: mu | sigma^2 ~ C(7.7, 1*sigma)
## (Assuming improper Jeffreys prior: p(sigma^2) = 1/sigma^2
##
## Posterior Summaries
## 2.5% 25% 50% 75% 97.5%
## mu 7.3859029 7.434046 7.459164 7.484224 7.533884
## sigma 1.0277250 1.058744 1.076079 1.094525 1.129520
## n_0 0.8612824 9.819322 23.762910 47.121973 129.102904
##
## 95% CI for mu: (7.3859, 7.5339)
Let’s look at the meanings of the arguments of this custom function. The first argument y specifies the response variable that we are interested in: weight. The second argument, data, specifies the dataset nc_fullterm that contains the variable weight. The third argument statistic is the sample statistic we’re using, or similarly, the population parameter we’re estimating. The argument type specifies the type of inference that we want: credible intervals (type = "ci"), or hypothesis tests (type = "ht"). The argument prior indicates which prior distribution for any unknown parameters we will use for inference or testing, with options JZS (the Jeffreys-Zellner-Siow prior which is the Jeffreys prior for the unknown variance and a Cauchy prior for the mean), JUI (the Jeffreys-Unit Information prior which is the Jeffreys prior for the variance and the Unit Information Gaussian prior for the mean), NG (the conjugate Normal-Gamma prior for the mean and inverse of the variance) or ref (the independent Jeffreys reference prior for the variance and the uniform prior for the mean). As we would like to use the same prior for constructing credible intervals and hypothesis testing later with results that are robust if we mis-specify the prior, we will use the JZS option. For all of the prior_family options, we need to specify prior hyperparameters. For JZS, the prior on standardized effect \(\mu/\sigma\) is a Cauchy centered at mu_0 and with a scale of rscale. By default these are zero and one respectively. The average birthweight for full term births in the US in 1994-1996 was 7.7 pounds, which we will use as the center of our prior distribution using the argument mu_0 = 7.7. We will use the default argument rscale = 1. The method of inference can be either method = "theoretical" (theoretical based) or "simulation" based; in the case of the JZS prior for credible intervals, "simulation" is the only option as there are no closed form results. We also specify that we are looking for the 95% credible interval by setting cred_level = 0.95, which is the default. For more information on the bayes_inference function see the help file with ?bayes_inference.
Which of the following corresponds to the 95% credible interval for the average birth weight of all full-term babies born in North Carolina?
We can also conduct a Bayesian hypothesis test by calculating Bayes factors or posterior probabilities. Let us test to see if the average birth weight in North Carolina for full term births is significantly different from the US average of 7.7 pounds from 1994-96. The two competing hypotheses are:
\[ H_1: \mu = 7.7 \] \[ H_2: \mu \ne 7.7 \]
To conduct this hypothesis test, we will need to change the type argument to hypothesis test, type = "ht" in the bayes_inference function. In addition, we will need to add the type of alternative hypothesis as an additional argument alternative = "twosided". For faster calculation, change the method to theoretical and add show_plot=FALSE.
Based of Jeffrey’s scale for interpretation of a Bayes factors how should we describe the evidence against \(H_1\) from your results for the hypothesis test?
# Type your code for the Exercise here.
bayes_inference(y = weight, data = nc_fullterm,
statistic = "mean", type = "ht", alternative="twosided",
prior_family = "JZS", mu_0 = 7.7, rscale = 1,
method = "theoretical",show_plot = FALSE,
cred_level = 0.95)
## Single numerical variable
## n = 846, y-bar = 7.4594, s = 1.075
## (Using Zellner-Siow Cauchy prior: mu ~ C(7.7, 1*sigma)
## (Using Jeffreys prior: p(sigma^2) = 1/sigma^2
##
## Hypotheses:
## H1: mu = 7.7 versus H2: mu != 7.7
## Priors:
## P(H1) = 0.5 , P(H2) = 0.5
## Results:
## BF[H2:H1] = 25478497
## P(H1|data) = 0 P(H2|data) = 1
A key advantage of Bayesian statistics is predictions and the probabilistic interpretation of predictions. Much of Bayesian prediction is done using simulation techniques, some of which was discussed near the end of this module. We will go over a simple simulation example to obtain the predictive distribution of the variable weight using the output of bayes_inference which we will save to the object weight_post:
weight_post = bayes_inference(y = weight, data = nc_fullterm,
statistic = "mean", type = "ci",
prior_family = "JZS", mu_0 = 7.7, rscale = 1,
method = "simulation",
cred_level = 0.95)
## Single numerical variable
## n = 846, y-bar = 7.4594, s = 1.075
## (Assuming Zellner-Siow Cauchy prior: mu | sigma^2 ~ C(7.7, 1*sigma)
## (Assuming improper Jeffreys prior: p(sigma^2) = 1/sigma^2
##
## Posterior Summaries
## 2.5% 25% 50% 75% 97.5%
## mu 7.3875487 7.434071 7.458988 7.483689 7.531830
## sigma 1.0270813 1.059314 1.075949 1.093548 1.130558
## n_0 0.9112563 9.754042 23.779722 47.596898 127.464071
##
## 95% CI for mu: (7.3875, 7.5318)
The names function can list the output or objects that are stored in the object created by bayes_inference:
names(weight_post)
## [1] "mu" "post_den" "cred_level" "post_mean" "post_sd"
## [6] "ci" "samples" "summary" "plot"
In particular, the samples object is a matrix or table which contain the draws from the MCMC simulation, and includes columns for mu and sig2, which are posterior samples of the mean and variance respectively. Let’s see how we can use these to make predictions.
The distribution of any new observation conditional on the mean and variance is \[N(\mu, \sigma^2)\] and if we knew \(\mu\) and \(\sigma^2\) we could draw a sample from the distribution of the new observation from the normal distribution. While we do not know \(\mu\) and \(\sigma^2\) we the draws of \(\mu\) and \(\sigma^2\) from their posterior distributions. If we substitute these values into the normal distribution for \(Y_{n+1}\), we can obtain samples from the predictive distribution for the birth weight for any new observation \(y_{1001}\).
We’ll first convert our samples into a dataframe and then use mutate the create draws from the predictive distribution using rnorm:
samples = as.data.frame(weight_post$samples)
nsim = nrow(samples)
samples = mutate(samples, y_pred = rnorm(nsim, mu, sqrt(sig2)))
We can view an estimate of the predictive distribution, by looking at a smoothed version of the histogram of the simulated data:
ggplot(data = samples, aes(x = y_pred)) +
geom_histogram(aes(y = ..density..), bins = 100) +
geom_density() +
xlab(expression(y[new]))
A 95% central credible interval for a new observation is the interval (L, U) where \(P(Y_{new} < L \mid Y) = 0.05/2\) and \(P(Y_{new} > U \mid Y) = 0.05/2)\). In this case, since the posterior distribution of \(\mu\) and \(Y_{new}\) are both symmetric, we can set L to be the 0.025 quantile and U to be the 0.975 quantile. Using the quantile function R we can find the 0.025 and 0.975, as well as median (0.50) quantiles of the predictive distribution:
dplyr::select(samples, mu, y_pred) %>%
map(quantile, probs=c(0.025, 0.50, 0.975))
## $mu
## 2.5% 50% 97.5%
## 7.387549 7.458988 7.531830
##
## $y_pred
## 2.5% 50% 97.5%
## 5.340936 7.447207 9.584111
In the above code we are using dplyr:select to select just the columns mu and y_pred from samples. The usage of dplyr: preceeding select, ensures that we are using the select function from the dplyr package to avoid possible name conflicts, as several packages have a select function. We are also taking advantage of the pipe operator to send the selected columns to the map function to apply the quantile function to each of the selected columns for the probabilities in the argument probs to quantile.
For predicting the birth weight of a new full term baby in NC,
# Type your code for Question 5 here.
Repeat the above analysis but find the predictive distribution for babies that were premature.
# Type your code for Exercise 2 here.
Next, let us consider whether there is a difference of baby weights for babies born to smokers and non-smokers. Here we will use the variable habit to distinguish between babies born to mothers who smoked and babies born to mothers who were non-smokers. Plotting the data is a useful first step because it helps us quickly visualize trends, identify strong associations, and develop research questions.
To create side by side boxplots by levels of a categorical variable x, we can use the following:
ggplot(nc, aes(x = habit, y = weight)) +
geom_boxplot()
to create side-by-side boxplots of weight for smokers and non-smokers.
Construct a side-by-side boxplot of habit and weight for the data using full term births and compare the two distributions. Which of the following is false about the relationship between habit and weight?
# Type your code for the question here.
ggplot(nc_fullterm, aes(x=habit, y=weight, fill=gender)) +
geom_boxplot() +
facet_wrap(~gender)
The box plots show how the medians of the two distributions compare, but we can also compare the means of the distributions using the following to first group the data by the habit variable, and then calculate the mean weight in these groups using the mean function, where the %>% pipe operator takes the output of one function and then pipes it into the next function.
nc_fullterm %>%
group_by(habit) %>%
summarise(mean_weight = mean(weight))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 2 x 2
## habit mean_weight
## <fct> <dbl>
## 1 nonsmoker 7.50
## 2 smoker 7.17
There is an observed difference, but is this difference statistically significant? In order to answer this question we will conduct a Bayesian hypothesis test.
As before, we can use the bayes_inference function to test the hypothesis the mean weight of babies born to non-smokers is different than the mean weight of babies born to smokers. The call is almost identical to the single mean case, except now we will provide habit as an explanatory variable (argument x = habit). Here, we use the theoretical method instead of simulation (argument method = "theoretical").
bayes_inference(y = weight, x = habit, data = nc_fullterm,
statistic = "mean",
type = "ht", alternative = "twosided", null = 0,
prior = "JZS", rscale = 1,
method = "theoretical", show_plot = FALSE)
## Response variable: numerical, Explanatory variable: categorical (2 levels)
## n_nonsmoker = 739, y_bar_nonsmoker = 7.5011, s_nonsmoker = 1.0833
## n_smoker = 107, y_bar_smoker = 7.1713, s_smoker = 0.9724
## (Assuming Zellner-Siow Cauchy prior on the difference of means. )
## (Assuming independent Jeffreys prior on the overall mean and variance. )
## Hypotheses:
## H1: mu_nonsmoker = mu_smoker
## H2: mu_nonsmoker != mu_smoker
##
## Priors: P(H1) = 0.5 P(H2) = 0.5
##
## Results:
## BF[H2:H1] = 6.237
## P(H1|data) = 0.1382
## P(H2|data) = 0.8618
Based on the Bayes factor calculated above, how strong is evidence against \(H_1\)?
How would the Bayes factor above change if we were to increase the prior probability of \(H_2\) to 0.75? (Hint: you may change the prior of \(H_1\) and \(H_2\) by specifying hypothesis_prior = c(a, b) where \(P(H_1) = a\), \(P(H_2) = b\), and \(a+b = 1\).)
# Type your code for the question here.
bayes_inference(y = weight, x = habit, data = nc_fullterm,
statistic = "mean",
type = "ht", alternative = "twosided", null = 0,
prior = "JZS", rscale = 1, hypothesis_prior=c(0.25,0.75),
method = "theoretical", show_plot = FALSE)
## Response variable: numerical, Explanatory variable: categorical (2 levels)
## n_nonsmoker = 739, y_bar_nonsmoker = 7.5011, s_nonsmoker = 1.0833
## n_smoker = 107, y_bar_smoker = 7.1713, s_smoker = 0.9724
## (Assuming Zellner-Siow Cauchy prior on the difference of means. )
## (Assuming independent Jeffreys prior on the overall mean and variance. )
## Hypotheses:
## H1: mu_nonsmoker = mu_smoker
## H2: mu_nonsmoker != mu_smoker
##
## Priors: P(H1) = 0.25 P(H2) = 0.75
##
## Results:
## BF[H2:H1] = 6.237
## P(H1|data) = 0.0507
## P(H2|data) = 0.9493
If differences between the groups are expected to be small, using a value of rscale = sqrt(2)/2 in the JZS prior is recommended.
How would the Bayes factor for H2 to H1 change if we were to change the scale in the Cauchy prior rscale = sqrt(2)/2?
# Type your code for Question 9 here.
bayes_inference(y = weight, x = habit, data = nc_fullterm,
statistic = "mean",
type = "ht", alternative = "twosided", null = 0,
prior = "JZS", rscale = sqrt(2)/2, hypothesis_prior=c(0.25,0.75),
method = "theoretical", show_plot = FALSE)
## Response variable: numerical, Explanatory variable: categorical (2 levels)
## n_nonsmoker = 739, y_bar_nonsmoker = 7.5011, s_nonsmoker = 1.0833
## n_smoker = 107, y_bar_smoker = 7.1713, s_smoker = 0.9724
## (Assuming Zellner-Siow Cauchy prior on the difference of means. )
## (Assuming independent Jeffreys prior on the overall mean and variance. )
## Hypotheses:
## H1: mu_nonsmoker = mu_smoker
## H2: mu_nonsmoker != mu_smoker
##
## Priors: P(H1) = 0.25 P(H2) = 0.75
##
## Results:
## BF[H2:H1] = 8.1113
## P(H1|data) = 0.0395
## P(H2|data) = 0.9605
To quantify the magnitude of the differences in mean birth weight, we can use a credible interval. Change the type argument to "ci" to construct and record a credible interval for the difference between the weights of babies born to nonsmoking and smoking mothers, and interpret this interval in context of the data. Note that by default you’ll get a 95% credible interval. If you want to change the confidence level, change the value for cred_level which takes on a value between 0 and 1. Also note that when doing a credible interval arguments like null and alternative are not useful, so make sure to remove them, but include the prior mean mu_0.
Based on the 95% credible interval for the differences in full term birth weights for nonsmokers and smoker:
# Type your code for Question 10 here.
bayes_inference(y = weight, x = habit, data = nc_fullterm,
statistic = "mean",
type = "ci", alternative = "twosided", null = 0,
prior = "JZS", rscale = sqrt(2)/2, hypothesis_prior=c(0.25,0.75),
method = "theoretical", show_plot = TRUE)
## Response variable: numerical, Explanatory variable: categorical (2 levels)
## n_nonsmoker = 739, y_bar_nonsmoker = 7.5011, s_nonsmoker = 1.0833
## n_smoker = 107, y_bar_smoker = 7.1713, s_smoker = 0.9724
## (Assuming Zellner-Siow Cauchy prior for difference in means)
## (Assuming independent Jeffrey's priors for overall mean and variance)
##
##
## Posterior Summaries
## 2.5% 25% 50% 75%
## overall mean 7.23324104 7.3031799 7.3399411 7.3769396
## mu_nonsmoker - mu_smoker 0.10538040 0.2463738 0.3198386 0.3911640
## sigma^2 1.04081324 1.1072735 1.1442742 1.1823798
## effect size 0.09764372 0.2300842 0.2992400 0.3650973
## n_0 74.22402418 813.4332589 1920.4959098 3856.3768805
## 97.5%
## overall mean 7.448620e+00
## mu_nonsmoker - mu_smoker 5.333007e-01
## sigma^2 1.258651e+00
## effect size 4.990810e-01
## n_0 1.043376e+04
## 95% Cred. Int.: (0.1054 , 0.5333)
The second data set comes from a 2008 study A simple tool to ameliorate detainees’ mood and well-being in Prison: Physical activities. The study was performed in a penitentiary of the Rhone-Alpes region (France), that includes two establishments, one for remand prisoners and short sentences (Jail) and the second for sentenced persons (Detention Centre, DC). A total number of 26 male subjects, imprisoned between 3 to 48 months, participated to the study. The participants were divided into two groups: 15 “Sportsmen” who chose spontaneously to follow the physical program; and 11 “References”, who did not and wished to remain sedentary. This data provide the perceived stress scale (PSS) of the participants in prison at the entry (PSSbefore) and at the exit (PSSafter).
We can load the PrisonStress data set into our workspace using the data function once the PairedData package is loaded.
data("PrisonStress")
This data set consists of 26 observations on 4 variables. They are summarized as follows:
| variable | description |
|---|---|
Subject |
anonymous subjects |
Group |
whether the subject chose to follow the physical programme Sport or not Control |
PSSbefore |
perceived stress measurement at the entry |
PSSafter |
perceived stress measurement at the exit |
We have two groups of observations: the sport group, the ones who chose to follow the physical training program; and the control group, the ones who chose not to follow. We are interested to know whether in average there is any difference in the perceived stress scale (PSS) before they started the training (at the entry) and after the training (at the exit).
We first analyze the control group data. We subset the data according to the Group variable using the dplyr package, and save this into a smaller data set PPS.control.
pss_control = PrisonStress %>%
filter(Group == "Control") %>%
mutate(diff = PSSbefore - PSSafter)
where the third line calculate the difference of the PSS of each subject before and after the training and saves it as a new variable diff.
We can now conduct the following hypothesis test: \[ H_1: \mu_{\text{before}} = \mu_{\text{after}}\qquad \Longrightarrow \qquad H_1: \mu_{\text{diff}} = 0, \]
\[ H_2: \mu_{\text{before}} \neq \mu_{\text{after}}\qquad \Longrightarrow \qquad H_1: \mu_{\text{diff}} \neq 0, \]
We use bayes_inference function to calculate the Bayes factor. The code is similar to the one we used for inference for one mean, except that we need to set null = 0, because we are comparing the mean of the difference to 0.
bayes_inference(y = diff, data = pss_control,
statistic = "mean",
type = "ht", alternative = "twosided", null = 0,
prior = "JZS", rscale = 1,
method = "simulation", show_plot = FALSE)
## Single numerical variable
## n = 11, y-bar = -7.3636, s = 9.2333
## (Using Zellner-Siow Cauchy prior: mu ~ C(0, 1*sigma)
## (Using Jeffreys prior: p(sigma^2) = 1/sigma^2
##
## Hypotheses:
## H1: mu = 0 versus H2: mu != 0
## Priors:
## P(H1) = 0.5 , P(H2) = 0.5
## Results:
## BF[H2:H1] = 2.7364
## P(H1|data) = 0.2676 P(H2|data) = 0.7324
While there appears to an increase in stress, based on Jeffrey’s scales of evidence, the evidence against H1 is `worth a bare mention’.
Conduct the same hypothesis test for the mean of the difference in perceived stress scale for the sport group. Based of Jeffrey’s scale for interpretation of a Bayes factors how should we describe the evidence against \(H_1\) from the results?
# Type your code for Question 11 here.
pss_sport = PrisonStress %>%
filter(Group == "Sport") %>%
mutate(diff = PSSbefore - PSSafter)
bayes_inference(y = diff, data = pss_sport,
statistic = "mean",
type = "ht", alternative = "twosided", null = 0,
prior = "JZS", rscale = 1,
method = "simulation", show_plot = FALSE)
## Single numerical variable
## n = 15, y-bar = 3.9333, s = 5.6753
## (Using Zellner-Siow Cauchy prior: mu ~ C(0, 1*sigma)
## (Using Jeffreys prior: p(sigma^2) = 1/sigma^2
##
## Hypotheses:
## H1: mu = 0 versus H2: mu != 0
## Priors:
## P(H1) = 0.5 , P(H2) = 0.5
## Results:
## BF[H2:H1] = 3.1232
## P(H1|data) = 0.2425 P(H2|data) = 0.7575
It is possible that other factors during this period of time could affect stress. By combining data from both groups we can increase our sample size, which provides greater power to detect a difference due to the intervention. If we assume that the variation in the two groups is comparable, we can use the differences in the before and after measurements to compare whether the intervention had an effect on stress levels.
Create a new data frame with a variable that is the difference in pre and post stress measurements and test the hypothesis that the mean difference in the control group is equal to the mean in the sport group versus the hypothesis that the means are not equal.
# Type your code for Exercise 2 here.