R: I have a linear correlation between two variables x and y, but need to control for a third variable that may be influencing the output. My question is about which test I should/ can use. Can I use a Pearson's correlation and add a covariate? If so, how? Or should I use a GLM with a covariate? How would these approaches differ? I am relatively new to R, so any help on the code would be helpful too. Thank you!


Yes, you can use correlation with a covariate. This is called partial correlation. It produces a (partial) correlation coefficient that is normalized to the [-1, 1] range just like a regular correlation coefficient, except that the covariate is "controlled for" in the analysis -- a concept which is kind of subtle, but some good explanations of what it really means can be found here.

One way to get a partial correlation in R is using the ppcor package:

# install/load 'ppcor' package for its pcor.test() function
  install.packages("ppcor", repos='http://cran.us.r-project.org')

# make up data
x <- rnorm(50)
y <- rnorm(50)
z <- rnorm(50)

# partial correlation between x and y, controlling for z
pcor.test(x, y, z)
#      estimate   p.value  statistic  n gp  Method
# 1 -0.02288511 0.8752972 -0.1569335 50  1 pearson

You also asked whether this differed from using a linear model with a covariate. It doesn't! Check it out:

summary(lm(y ~ x + z))
# Call:
# lm(formula = y ~ x + z)
# Residuals:
#      Min       1Q   Median       3Q      Max 
# -2.80457 -0.76631 -0.00539  0.64083  2.79261 
# Coefficients:
#             Estimate Std. Error t value Pr(>|t|)
# (Intercept)  0.05163    0.17006   0.304    0.763
# x           -0.02486    0.15842  -0.157    0.876
# z            0.07098    0.15333   0.463    0.646
# Residual standard error: 1.184 on 47 degrees of freedom
# Multiple R-squared:  0.005408,    Adjusted R-squared:  -0.03692 
# F-statistic: 0.1278 on 2 and 47 DF,  p-value: 0.8804

Notice that most of the numbers for the "x" row in the lm() output match those that we got from pcor.test(). The only difference is that the "estimate" for pcor.test() is the partial correlation coefficient, while the "estimate" for lm() is the slope. (The two estimates happen to be numerically similar here, but they are NOT the same.)

  • $\begingroup$ We are trying to build a permanent repository of high-quality statistical information in the form of questions & answers. We try to avoid overly brief and link-only answers which are subject to link-rot; indeed such answers may be deleted. As such this is more of a comment than an answer in its own right. If you're able, could you expand it, perhaps by giving a summary of the information at the link(s). Alternatively, we can convert it into a comment for you. $\endgroup$ – Glen_b Sep 7 '15 at 23:08
  • $\begingroup$ @Glen_b I agree this feels more like a comment than an answer, my thought was that I wanted to avoid posting yet another comment that is actually an answer. But if you think this is still better off as a comment, that's fine with me. $\endgroup$ – Jake Westfall Sep 8 '15 at 1:05
  • $\begingroup$ Well, my preference would be to have you expand on the answer so it actually contains some of the information you point to -- then it would be a good answer. [The objection to link only answers is a SE-network-wide policy, as is the objection to answers in comments; the solution is to give answers that also outline the information at the link, and then give the link as reference, support and for additional information.] $\endgroup$ – Glen_b Sep 8 '15 at 1:36
  • $\begingroup$ @Glen_b Okay, I'll expand on the answer before going to bed. I do appreciate you taking the time to attend to and enforce issues like this that ultimately make the site a better place. $\endgroup$ – Jake Westfall Sep 8 '15 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.