Getting started with planned contrasts in R  | Towards Data Science

It’s a situation many of us face: You just ran an ANOVA, and your results are significant... but what next? We basically know that something is going on, but what exactly? Which treatments are making the difference?
This is where planned contrasts come in. They sound more complicated than they are, and they are a flexible statistical tool that makes this ANOVA post-hoc test extremely powerful.
Just a quick note before I get going: In this tutorial, I will just talk about orthogonal contrast ... you do not need to know what this means, just in case you heard the term, and we're looking for this.
For this tutorial, we will be using the salaries dataset. It contains data on the salaries of different professors. Load it using the following command.
df=Salaries
We will need the “car” package for the next step, so install the package using the below command if you haven’t done so already. If you aren’t sure whether you’ve already installed the package, just run this command.
install.packages("car")
Now, the ANOVA we want to do is to see whether the professors' rank has any impact on their salary. We also want to take all other intuitively important variables into account ... technically making this an ANCOVA. We run the below commands to get the output.
library(car)aov1 = aov(salary ~ sex + rank + yrs.since.phd + yrs.service + discipline, df)Anova(aov1 ,type="III")
This yields the following result.
So we can see that rank does influence the salary of the professors. But how exactly? Planned contrasts can help us find out more about this. However, planned contrasts require that you really understand your independent variable of interest.
Let’s look at the independent variable of interest first. What does “rank” contain. For this, run the following command to see the levels of “rank.”
levels(df$rank)
This yields the following output.
In the US ... and this is an American dataset ... there is a huge difference between being an assistant professor and being an associate professor. Associate professors are part of faculty and are most often tenured. Assistant professors aren’t part of faculty and most often not tenured. A question planned contrasts can help us answer is, “Is being an Associate Professor important for a professor’s salary, or is it important to be part of the faculty?” ... do you see what we are doing here? We are using implicit information in the data to group our levels in new ways and reveal more information about the effect's true underlying drivers. Basically, we are saying ... “We know that there are three levels, but how can we group these levels to reveal more information?” — we are contrasting groups of data.
You would normally run two planned contrasts in a situation like this: First, you would want to see if being part of faculty makes a difference. Second, you would want to see if differences within faculty make a difference. Below is a graphical representation of what we are trying to achieve.
We communicate this to R with the help of orthogonal contrasts, which use a specific notation. The notation consists of four rules:
We use zero (0) for groups excluded from a contrast.
We use negative values (<0) for the baseline group.
We use positive values (>0) for the treatment group.
The sum of the treatments' values in every contrast needs to be zero (0).
This doesn't sound very easy but is very simple once you see how this plays out for the example. The contrasts in the schematic would be communicated to R in the following way:
Contrast 1: In the first contrast, we group AssocProf and Prof into the treatment condition. Therefore, they both are assigned a positive value. To keep things simple, we choose a low value (1). As AssistProf is now the baseline, needs to be negative, and contrast 1 in total needs to add up to zero (0), we are required to assign it a -2.
Contrast 2: In the second contrast, we only want to see whether differences among tenured positions impact the salary. Therefore, we exclude AsstProf by assigning it a 0. We choose to make Prof the treatment condition and AssocProf the baseline condition ... we could also switch the two of them, but changes in direction are dangerous as we might forget about them when we later interpret the results. To keep things simple, we keep the direction as it is (treatment is the more senior condition). Also, to keep things simple, we again choose low values and assign the treatment condition Prof a 1. Therefore, the baseline condition AssocProf has to be a -1, as the contrast in total needs to add up to 0.
This is exactly how we communicate the assigned contrasts to R.
contrast1 = c(-2,1,1)contrast2 = c(0,-1,1)
And then, we tell R to assign these contrasts to the variable rank in the dataset df.
contrasts(df$rank) = cbind(contrast1, contrast2)
To check if the contrasts were assigned correctly, we can repeat the contrast() command to see how they are now saved in R.
contrasts(df$rank)
As we can see, they have been implemented correctly. So now we can proceed with our analysis.
We analyze our contrasts by rerunning the same ANOVA command that we ran before. However, because now R has more information on the structure of the variable rank in the form of contrasts, the output will be different.
aov1 = aov(salary ~ sex + rank + yrs.since.phd + yrs.service + discipline, df)
And this time, we do not want to access the information in the form of an ANOVA output but in the form of regression output. Therefore, we ask for the output using the summary.lm command.
summary.lm(aov1)
As one can see, R now produces output, in which the levels of the variable rank are replaced with the two contrasts. Both contrasts are significant, meaning that becoming tenured affects professors’ salaries and so does moving up among tenured positions.
We would report this finding in the following way:
An ANOVA revealed that there was a significant effect of professors’ ranks on their salaries (F(2, 390) = 68.41, p < .001) while controlling for their sex, the number of years since they completed their PhD, the number of years of service, and the academic discipline they work in. Further investigation of the impact of professors’ ranks on their salaries using planned contrasts revealed that being faculty (associate or full professor) was associated with a significant increase in salary compared to being an assistant professor, t(390) = 7.64, p < .001 (two-tailed), and that once being faculty, being a full professor instead of an associated professor was associated with a further increase, t(390) = 9.08, p < .001 (two-tailed).