4 Workshop 4: One-Way ANOVA (Model, Designs, Assumptions)
Aims:
- Practice running one-way ANOVAs for both repeated and independent measures designs.
- Practice checking ANOVA assumptions and interpreting the ANOVA model output.
Part One
Part one of today’s workshop will involve running a one-way ANOVA for a repeated measures design.
Mild cognitive impairment (MCI) occurs wen someone begins to have difficulty with their memory or other cognitive abilities, however, these are (1) not usually significant enough to interfere with general activities of daily living and (2) do not fully meet the criteria for dementia.
This data set contains data from a new memory assessment used for individuals with MCI across a four year period (each participant was assessed once per year).
Using a one-way ANOVA, can you determine what happens to memory scores over time?
4.1 Exercise 1: Import the Data
Import the Data File
Before you begin you will need a few packages loaded.
library(tidyverse) # should already be installed.
install.packages("afex") # install if needed
install.packages("car") #install if needed
library(afex)
library(car)Next import the data file and store it as an object called dat.
dat <- read_csv("mci.csv")4.2 Exercise 2: Inspect and Check Your Data
Take a look at your newly imported data file
Check the top right panel (the environment) and also use the code below to inspect your dataset.
Is this data in wide format or long format?
If the data is wide, you will need to convert it to long format using the code below.
mydata <- dat %>%
pivot_longer(cols = year1:year4,
names_to = "time",
values_to = "memory")Here is an explanation of this code line by line. This one is a little tricky.
First, create a new object called
mydataand base it on the existingdatand then…Pivot the data (from long to wide) by taking all columns starting with
year1through toyear4. By statingyear1:year4you are telling to take all columns fromyear1through toyear4, including anything in between. Essentially you are stating the first and final levels of your independent variable.names_toshould include a name you assign to the independent variable. In this study it is time point but we will just usetimeas it is shorter.values_toshould include a name you assign to the dependent variable. In this study it was memory assessment score, but we will just usememory.
Run the code and then check mydata to see if it worked.
From now on we will only use the mydata object, as it is in long format.
4.3 Exercise 3: Check Descriptives
Using the code below, generate descriptive statistics to look at the mean memory score across time.
desc <- mydata %>%
group_by(time) %>%
summarise(m_memory = mean(memory),
sd_memory = sd(memory))
view(desc) # view the descriptive statsAlso, visualise the data using a box plot or density plot.
ggplot(mydata, aes(x = time, y = memory)) +
geom_boxplot(width = .4)ggplot(mydata, aes(x = memory, fill = time)) +
geom_density(alpha = .5)
facet_wrap() is missing from the density plots, however, if you feel it would be beneficial to aid interpretation, you can add it.
4.4 Exercise 4: Check Assumptions
Run the ANOVA model
Before we start looking at assumptions, we do need to run and store the initial ANOVA model.
mod <- aov_ez(id = "id",
dv = "memory",
within = "time",
type = 3,
include_aov = TRUE,
data = mydata)Checking Normality
First, look to see if the assumption of normality was met. You should look at three things.
- The QQ-Plot
- The histogram
- The Shapiro-Wilk test
#testing normality, looking at normal distribution of residuals from the model.
residuals <- residuals(mod) #pulls residuals from the model
# produce QQ-Plot
qqPlot(residuals) #produces a qq-plot of residuals
# produce histogram of residuals
hist(residuals, breaks = 20, main = "Histogram of Residuals", xlab = "Residuals", col = "lightblue")
# Shapiro test on residuals
shapiro.test(residuals) #Shapiro test for residualsChecking Sphericity
To check sphericity, we need to produce the model output.
summary(mod) # provides the output of the main ANOVA model with Sphericity output.Look through the output to find: “Mauchly Tests for Sphericity”.
It will provide a test statistic, reported using W = XX.XX
It will provide a p-value statistic. For this test, a non-significant p-value means the assumption was met. A non-significant p-value is one that is a larger value than .05. A significant p-value is one smaller than .05.
It looks as though this p-value is smaller than .05 and so the assumption is violated. uh-oh!
4.5 Exercise 5: Interpret the ANOVA Model
For an easier and more streamlined output to interpret the model, use the code below:
mod$anova_tableYou should interpret this the same way as was explained in the lecture. Particularly noting the F, degrees of freedom (two values), and p-value (noting whether it was significant or not).
This model simply tells us: Should we reject the null hypothesis.
As this is a significant result, F(2.15, 105.54) = 127.16, p<.001, then we can reject our null hypothesis as at least one of the conditions differs. How they differ we do not yet know and you will learn about that next week…
4.6 Part 2 - Exercise 6: Import the Data
Part Two
In this part of the workshop you should conduct a one-way ANOVA for an independent measures design. The general interpretation is the same as above, but as covered in the lecture, the assumptions differ slightly.
In this study, participants were placed into one of three groups based on their circadian chronotype: in other words, are they an early bird (morning person), night owl (evening person), or neither (do not fit into either category). This means we have three independent groups.
You can try this out yourself here: link. Probably best to try this after your workshop.
The research question here is a simple one: does the early bird really catch the worm? or more scientifically put…who is more alert when completing an attention task at 9am.
The independent variable is circadian chronotype, 3 levels. The dependent variable is score on an attention task from 0-100 (100 is highly alert/top score).
Import the data
The file is called alert.csv. Import the data file and save it as an object called mydata1 (as to not overwrite anything from Part 1 in case you want to look back)
4.7 Exercise 7: Check Descriptives
Amend the code below to produce descriptive statistics.
names(mydata1) # might be useful to check variable names
view(mydata1) # might be useful to look at the data
desc1 <- mydata1 %>%
group_by(NULL1) %>%
summarise(mean_score = mean(NULL2),
sd_score = sd(NULL2))Change:
NULL1to the variable you want to split the data by. This should be the independent variable. This should be the dependent variable as it is names inmydata1.NULL2to the variable you want to calculate the mean and sd for. This should be the dependent variable as it is names inmydata1.
Also use this code to visualise the data to see what is going on.
ggplot(mydata1, aes(x = group, y = score)) +
geom_boxplot(width = .4)
ggplot(mydata1, aes(x = score, fill = group)) +
geom_density(alpha = .5)4.8 Exercise 8: Check Assumptions
Before we start looking at assumptions, we do need to run and store the initial ANOVA model. There are four NULL values you need to change in the code below to match your new data set.
We will save the model as an object called mod1.
mod1 <- aov_ez(id = "NULL",
dv = "NULL",
between = "NULL",
type = 3,
include_aov = TRUE,
data = NULL)Checking Normality
First, look to see if the assumption of normality was met. You should look at three things.
- The QQ-Plot
- The histogram
- The Shapiro-Wilk test
#testing normality, looking at normal distribution of residuals from the model.
residuals <- residuals(mod1) #pulls residuals from the model, note name is `mod1`
# produce QQ-Plot
qqPlot(residuals) #produces a qq-plot of residuals
# produce histogram of residuals
hist(residuals, breaks = 20, main = "Histogram of Residuals", xlab = "Residuals", col = "lightblue")
# Shapiro test on residuals
shapiro.test(residuals) #Shapiro test for residualsChecking Homogeneity of Variance
Run and interpret Levene’s test using the code below:
leveneTest(score ~ group, mydata1)4.9 Exercise 9: Interpret the ANOVA Model
Use the code below to interpret the ANOVA model. Decide if the model is significant and whether you can reject the null hypothesis. Also check back at the descriptive statistics to see if you can work out what could be going on.
mod1$anova_table| Well Done. You have reached the end of the workshop |