By John M Quick

The R Tutorial Series provides a collection of user-friendly tutorials to people who want to learn how to use R for statistical analysis.


My Statistical Analysis with R book is available from Packt Publishing and Amazon.


R Tutorial Series: One-Way Repeated Measures ANOVA

Repeated measures data require a different analysis procedure than our typical one-way ANOVA and subsequently follow a different R process. This tutorial will demonstrate how to conduct one-way repeated measures ANOVA in R using the Anova(mod, idata, idesign) function from the car package.

Tutorial Files

Before we begin, you may want to download the sample data (.csv) used in this tutorial. Be sure to right-click and save the file to your R working directory. This dataset contains a hypothetical sample of 30 participants whose interest in voting was measured at three different ages (10, 15, and 20). The interest values are represented on a scale that ranges from 1 to 5 and indicate how interested each participant was in voting at each given age.

Data Setup

Notice that our data are arranged differently for a repeated measures ANOVA. In a typical one-way ANOVA, we would place all of the values of our independent variable in a single column and identify their respective levels with a second column, as demonstrated in this sample one-way dataset. In a repeated measures ANOVA, we instead treat each level of our independent variable as if it were a variable, thus placing them side by side as columns. Hence, rather than having one vertical column for voting interest, with a second column for age, we have three separate columns for voting interest, one for each age level.

Beginning Steps

To begin, we need to read our dataset into R and store its contents in a variable.
  1. > #read the dataset into an R variable using the read.csv(file) function
  2. > dataOneWayRepeatedMeasures <- read.csv("dataset_ANOVA_OneWayRepeatedMeasures.csv")
  3. > #display the data
  4. > #notice the atypical column arrangement for repeated measures data
  5. > dataOneWayRepeatedMeasures

The first ten rows of our dataset

Preparing the Repeated Measures Factor

Prior to executing our analysis, we must follow a small series of steps in order to prepare our repeated measures factor.

Step 1: Define the Levels

  1. > #use c() to create a vector containing the number of levels within the repeated measures factor
  2. > #create a vector numbering the levels for our three voting interest age groups
  3. > ageLevels <- c(1, 2, 3)

Step 2: Define the Factor

  1. > #use as.factor() to create a factor using the level vector from step 1
  2. > #convert the age levels into a factor
  3. > ageFactor <- as.factor(ageLevels)

Step 3: Define the Frame

  1. > #use data.frame() to create a data frame using the factor from step 2
  2. > #convert the age factor into a data frame
  3. > ageFrame <- data.frame(ageFactor)

Step 4: Bind the Columns

  1. > #use cbind() to bind the levels of the factor from the original dataset
  2. > #bind the age columns
  3. > ageBind <- cbind(dataOneWayRepeatedMeasures$Interest10, dataOneWayRepeatedMeasures$Interest15, dataOneWayRepeatedMeasures$Interest20)

Step 5: Define the Model

  1. > #use lm() to generate a linear model using the bound factor levels from step 4
  2. > #generate a linear model using the bound age levels
  3. > ageModel <- lm(ageBind ~ 1)

Employing the Anova(mod, idata, idesign) Function

Typically, researchers will choose one of several techniques for analyzing repeated measures data, such as an epsilon-correction method, like Huynh-Feldt or Greenhouse-Geisser, or a multivariate method, like Wilks' Lambda or Hotelling's Trace. Conveniently, having already prepared our data, we can employ a single Anova(mod, idata, idesign) function from the car package to yield all of the relevant repeated measures results. This allows us simplicity in that only a single function is required, regardless of the technique that we wish to employ. Thus, witnessing our outcomes becomes as simple as locating the desired method in the cleanly printed results.
Our Anova(mod, idata, idesign) function will be composed of three arguments. First, mod will contain our linear model from Step 5 in the preceding section. Second, idata will contain our data frame from Step 3. Third, idesign will contain our factor from Step 2, preceded by a tilde (~). Thus, our final function takes on the following form.
  1. > #load the car package (install first, if necessary)
  2. library(car)
  3. > #compose the Anova(mod, idata, idesign) function
  4. > analysis <- Anova(ageModel, idata = ageFrame, idesign = ~ageFactor)

Visualizing the Results

Finally, we can use the summary(object) function to visualize the results of our repeated measures ANOVA.
  1. > #use summary(object) to visualize the results of the repeated measures ANOVA
  2. > summary(analysis)

Relevant segment of repeated measures ANOVA results

Supposing that we are interested in the Wilks' Lambda method, we can see that the differences in the means for voting interest at ages 10, 15, and 20 are statistically significant (p < .001).

Pairwise Comparisons

Note that we could conduct follow-up comparisons on our age factor to determine which age level means are significantly different from one another. For this purpose, it is recommended that the data be rearranged into the standard ANOVA format that we have used throughout our other tutorials. Subsequently, we could conduct pairwise comparisons in the same manner as demonstrated in the One-Way ANOVA with Comparisons tutorial.

Complete One-Way Repeated Measures ANOVA Example

To see a complete example of how one-way repeated measures ANOVA can be conducted in R, please download the one-way repeated measures ANOVA example (.txt) file.

R Tutorial Series: One-Way ANOVA with Pairwise Comparisons

When we have more than two groups in a one-way ANOVA, we typically want to statistically assess the differences between each group. Whereas a one-way omnibus ANOVA assesses whether a significant difference exists at all amongst the groups, pairwise comparisons can be used to determine which group differences are statistically significant.

Tutorial Files

Before we begin, you may want to download the sample data (.csv) used in this tutorial. Be sure to right-click and save the file to your R working directory. This dataset contains a hypothetical sample of 30 participants who are divided into three stress reduction treatment groups (mental, physical, and medical). The values are represented on a scale that ranges from 1 to 5. This dataset can be conceptualized as a comparison between three stress treatment programs, one using mental methods, one using physical training, and one using medication. The values represent how effective the treatment programs were at reducing participant's stress levels, with higher numbers indicating higher effectiveness.

Beginning Steps

To begin, we need to read our dataset into R and store its contents in a variable.
  1. > #read the dataset into an R variable using the read.csv(file) function
  2. > dataOneWayComparisons <- read.csv("dataset_ANOVA_OneWayComparisons.csv")
  3. > #display the data
  4. > dataOneWayComparisons

The first ten rows of our dataset.

Omnibus Test

One way to begin an ANOVA is to run a general omnibus test. The advantage to starting here is that if the omnibus test comes up insignificant, you can stop your analysis and deem all pairwise comparisons insignificant. If the omnibus test is significant, you should continue with pairwise comparisons.
  1. > #use anova(object) to test the omnibus hypothesis
  2. > #Is there a significant difference amongst the treatment means?
  3. > anova(lm(StressReduction ~ Treatment, dataOneWayComparisons))
The omnibus ANOVA test

Pairwise Comparisons

Since the omnibus test was significant, we are safe to continue with our pairwise comparisons. To make pairwise comparisons between the treatment groups, we will use the pairwise.t.test() function, which has the following major arguments.
  • x: the dependent variable
  • g: the independent variable
  • p.adj: the p-value adjustment method used to control for the family-wise Type I error rate across the comparisons; one of "none", "bonferroni", "holm", "hochberg", "hommel", "BH", or "BY"
The pairwise.t.test() function can be implemented as follows.
  1. > #use pairwise.t.test(x, g, p.adj) to test the pairwise comparisons between the treatment group means
  2. > #What significant differences are present amongst the treatment means?
  3. > pairwise.t.test(dataOneWayComparisons$StressReduction, dataOneWayComparisons$Treatment, p.adj = "none")

Pairwise comparisons of treatment group means

Note that the desired p-adjustment method will vary by researcher, study, etc. Here, we will assume an alpha level of .05 for all tests, effectively making no adjustment for the family-wise Type I error rate.
These results indicate that there is a statistically significant difference between the mental and medical (p = .004) and physical and medical (p = 0.045), but not the mental and physical (p = 0.302) treatments. The treatment means are 3.5 for mental, 3 for physical, and 2 for medical. Subsequently, we are inclined to conclude based on this study that the mental and physical treatments lead to greater stress reduction than the medical method, but that there is insufficient statistical support to determine that either the mental or physical treatment method is superior.

Complete One-Way ANOVA with Pairwise Comparisons Example

To see a complete example of how one-way ANOVA pairwise comparisons can be conducted in R, please download the one-way ANOVA comparisons example (.txt) file.

References

R Documentation (n.d.). Adjust P-values for Multiple Comparisons. Retrieved January 16, 2011 from http://stat.ethz.ch/R-manual/R-devel/library/stats/html/p.adjust.html

R Tutorial Series: One-Way Omnibus ANOVA

Testing the omnibus hypothesis via one-way ANOVA is simple process in R. This tutorial will explore how R can be used to perform a one-way ANOVA to test the difference between two (or more) group means.

Tutorial Files

Before we begin, you may want to download the sample data (.csv) used in this tutorial. Be sure to right-click and save the file to your R working directory. This dataset contains a hypothetical sample of 60 participants, who are divided into two groups (control and treatment) of 30. The values represent a scale that ranges from 1 to 5. For instance, this dataset could be conceptualized as a comparison between two professional training programs, where the control group participated the company's longstanding program and the treatment group participated in an experimental program. The values could represent the attitudes of employees towards the training programs on a scale from 1 (poor) to 5 (excellent).

Beginning Steps

To begin, we need to read our dataset into R and store its contents in a variable.
  1. > #read the one-way ANOVA dataset into an R variable using the read.csv(file) function
  2. > dataOneWay <- read.csv("dataset_ANOVA_OneWay.csv")
  3. > #display the data
  4. > dataOneWay

The first ten rows of our one-way ANOVA dataset.

One-Way ANOVA

Now that our data are ready, we can conduct a one-way omnibus ANOVA test using the anova(object) function.
  1. > #use anova(object) to test the omnibus hypothesis in one-way ANOVA
  2. > #is the difference between the group means statistically significant?
  3. > anova(lm(Values ~ Group, dataOneWay))

Our one-way ANOVA table.

The output of our ANOVA test indicates that the difference between our group means is statistically significant (p < .001). Conceptually, this suggests that employee attitudes towards the experimental training program were significantly higher than their attitudes towards the preexisting program.
Note that the object argument in our anova(object) function contained a linear model generated by the lm(formula, data) function. This is the same type of model that is used when conducting linear regression in R. A more detailed explanation of the lm(formula, data) function and examples of its use are available in my Simple Linear Regression article.

One-Way Multiple Group ANOVA

Conducting a one-way omnibus ANOVA with multiple groups is identical to the demonstrated two-group test. The only difference is that the values in your dataset would be associated with more than two groups. Subsequently, the omnibus hypothesis would test for mean differences across all of the groups. The anova(object) function and its contained lm(formula, data) function would remain the same.

Complete One-Way Omnibus ANOVA Example

To see a complete example of how a one-way omnibus ANOVA can be conducted in R, please download the one-way ANOVA example (.txt) file.