他の関数だとna.rm = TRUEにするような場面で、少し手こずったので備忘録。
データにNAが含まれている場合、そのまま相関係数を計算しようとすると結果がNAになってしまう。
# Data generation set.seed(3) x = runif(20,0,1) y = 0.7*x + 0.3*runif(20,0,1) z = 0.5*x + 0.5*runif(20,0,1) df = data.frame(x,y,z) # Make "NA" observations df$x[19] = NA # 19th observation of x is missing df$y[15] = NA # 15th observation of y is missing # Correlation cor(df$x,df$y)
計算結果は、
> cor(df$x,df$y) [1] NA
この場合は、cor( , use = "complete.obs")を使う。
# Correlation with NA cor(df$x,df$y, use = "complete.obs")
きちんと計算できる。
> cor(df$x,df$y, use = "complete.obs") [1] 0.8486316
これは、NAを含む組み合わせを取り除いたデータで相関を計算したものと同じになる。
# NA removed data df2 = df[-c(15,19),] cor(df2$x,df2$y)
>cor(df2$x,df2$y) [1] 0.8486316
このuseという引数は、デフォルトがeverythingになっていて、その場合はNAも含めてしまうので結果がNAになってしまうらしい。complete.obsは組み合わせが完全なもの(xもyもNAでないもの)だけ使うので上記のようになる。
この引数は他に、"all.obs"という値が取れるが、これは組み合わせが完全でない場合はエラーになる。(これをデフォルトにしてくれればいいのにと思う。)
"na.or.complete"という値もとれて、これはもし完全な組み合わせが一つもない場合は、NAを返すが、他はcomplete.obsと同じ扱いになる。
use引数の値をまとめると以下のようになる。
値* | 内容* |
---|---|
everything | デフォルト。すべての組み合わせを使うので、一つでもNAが入っていると相関係数にNAを返す。 |
complete.obs | 組み合わせが完全なものだけを使う。NAが入っている組み合わせは除外。 |
all.obs | 与えられた組み合わせが完全でないならエラーを返す。 |
na.or.complete | complete.obsを同じだが、完全な組合せがない場合はNAを返す。 |
pairwise.complete.obs | 3変数以上の場合に有効。以下参照。 |
pairwise.complete.obsというものがある。cor()は変数だけでなく行列やデータフレームを取れるが、変数が3つ以上ある場合は、それぞれの組み合わせの相関係数全てを計算する。complete.obsを使ってしまうと、例えばx,y,zという3つの変数があってxの19番目がNAである場合、yもzも19番目が使われないで計算ので、yとzの相関も19番目が使われずに計算される。一方で、pairwiseならxとの相関は19番目が使われないが、yとzの相関は19番目は両方あるので、19番目も使って計算する。
以下の結果で、それぞれxとyの、zとの相関係数が異なっているところに注目。complete.obsの場合は、xとz、yとzの相関係数は15番目と19番目の両方が使われずに計算されるが、pairwiseだとxとzなら15番目、yとzなら19番目も使って計算されるので結果が異なる。xとyはいずれにせよNAである15番目と19番目が除外されるので、結果が変わらない。
> cor(df, use = "complete.obs") x y z x 1.0000000 0.8486316 0.8210445 y 0.8486316 1.0000000 0.6766876 z 0.8210445 0.6766876 1.0000000 > cor(df, use = "pairwise.complete.obs") x y z x 1.0000000 0.8486316 0.8474716 y 0.8486316 1.0000000 0.6225771 z 0.8474716 0.6225771 1.0000000 ||< 参考URLはstackoverflowの質問である。