5

i'm trying to get the Pearson correlation coefficient for all rows in a data frame relative to each other. there are values that are empty (NA) and this seems to be presenting a problem that I don't encounter when running cor() on 2 vectors with missing values. This is the correct result on 2 vectors:

x <- c(NA, 4.5, NA, 4, NA, 1)
y <- c(2.5, 3.5, 3, 3.5, 3, 2.5)
cor(x,y, use = "complete.obs")
[1] 0.9912407

and here is the result when they are part of a data frame:

cor(t(critics1), use = "complete.obs")
   y  a  b  c  d  e  x
y  1 NA NA NA NA NA NA
a NA  1  1  1 -1  1 -1
b NA  1  1  1 -1  1 -1
c NA  1  1  1 -1  1 -1
d NA -1 -1 -1  1 -1  1
e NA  1  1  1 -1  1 -1
x NA -1 -1 -1  1 -1  1
Warning message:
In cor(t(critics1), use = "complete.obs") : the standard deviation is zero

Why is the use parameter not having the same effect? Here is what the critics1 dataframe looks like;

film1 film2 film3 film4 film5 film6
y   2.5   3.5   3.0   3.5   3.0   2.5
a   3.0   3.5   1.5   5.0   3.0   3.5
b   2.5   3.0    NA   3.5   4.0    NA
c    NA   3.5   3.0   4.0   4.5   2.5
d   3.0   4.0   2.0   3.0   3.0   2.0
e   3.0   4.0    NA   5.0   3.0   3.5
x    NA   4.5    NA   4.0    NA   1.0
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
hawkhandler
  • 243
  • 1
  • 4
  • 9
  • What does the data.frame `critics1` look like? Could you include a few rows in your question? – Josh O'Brien Dec 06 '11 at 18:59
  • 2
    Maybe there are actually no complete observations in your matrix, in which case you might need to use `pairwise.complete.obs`? Only way to know for sure is to share the structure of your matrix, as Josh says. – joran Dec 06 '11 at 19:02
  • 1
    @joran. Bingo. There are only two complete observations, and (to boot), y shows no variance among them. With `pairwise.complete.obs`, it works just fine. – Josh O'Brien Dec 06 '11 at 19:17

1 Answers1

7

As @joran speculated, when you transpose critics1, there are only two complete observations (i.e. rows with no missing values). That's why all of the correlations are either 1 or -1 or (for those involving y, which has value 3.5 in both complete rows), NA.

t(critics1)
#         y   a   b   c d   e   x
# film1 2.5 3.0 2.5  NA 3 3.0  NA
# film2 3.5 3.5 3.0 3.5 4 4.0 4.5
# film3 3.0 1.5  NA 3.0 2  NA  NA
# film4 3.5 5.0 3.5 4.0 3 5.0 4.0
# film5 3.0 3.0 4.0 4.5 3 3.0  NA
# film6 2.5 3.5  NA 2.5 2 3.5 1.0

If you use use="pairwise.complete.obs" instead of use="complete.obs", it works as you'd like:

cor(t(df), use="pairwise.complete.obs")["y","x"] # Extract correlation of y and x
# [1] 0.9912407
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455