本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:相関行列をggplot2で可視化する「ggcorrplot」パッケージ

複数の変数をまとめて扱うとき、変数の関係を一覧できると、データの全体像が伝わりやすくなります。しかし、相関行列を数値のまま眺めても関係の強弱はつかみにくく、似た変数どうしの並び替えや、有意でない相関の除外は手間がかかります。

「ggcorrplot」パッケージは、相関行列の可視化をggplot2の作図として簡単におこなえるパッケージです。相関行列を正方形や円のマップとして描画するコマンド、相関係数のp値行列を算出するコマンドが収録されています。

他にも階層的クラスタリングによる並び替え、クラスターを囲む矩形の描画、有意でないセルの空白化や記号の重ね描き、相関係数ラベルへの星印の付加が可能です。また、上三角と下三角で異なる表現を組み合わせた混合レイアウトや、色覚多様性に配慮した配色の一括指定も可能です。

パッケージバージョンは0.3.0。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
install.packages("ggcorrplot")

# パッケージの読み込み
library("ggcorrplot")
スポンサーリンク

コマンド例

詳細はコメント、パッケージのヘルプを確認してください。

以下の例では、架空の和菓子店24店舗の月次データを使用します。

# 架空の和菓子店24店舗の月次データを作成
wagashi <- data.frame(
  店舗名 = paste0("和菓子店", sprintf("%02d", 1:24)),
  来客数 = c(111, 180, 97, 209, 130, 168, 181, 224, 77, 131, 184, 194,
          190, 103, 143, 183, 170, 183, 105, 145, 202, 118, 187, 171),
  平均単価 = c(490, 650, 800, 450, 740, 650, 560, 880, 730, 500, 650, 710,
           620, 720, 630, 720, 810, 560, 660, 580, 660, 500, 570, 620),
  月間売上 = c(163, 282, 199, 235, 224, 295, 263, 514, 135, 177, 303, 356,
           290, 175, 254, 335, 362, 266, 174, 211, 356, 149, 275, 276),
  駅徒歩分 = c(12, 4, 14, 3, 11, 10, 8, 1, 15, 13, 7, 6,
           2, 17, 10, 5, 12, 5, 18, 15, 3, 16, 7, 9),
  席数 = c(30, 39, 13, 26, 29, 12, 24, 32, 30, 28, 26, 26,
         31, 30, 23, 28, 26, 29, 17, 13, 31, 17, 36, 31),
  SNS投稿 = c(33, 62, 25, 75, 39, 57, 39, 71, 4, 15, 52, 47,
            59, 58, 33, 47, 53, 61, 29, 41, 69, 42, 44, 50),
  口コミ点 = c(3.4, 3.5, 3.7, 3.5, 3.8, 3.7, 3.5, 3.8, 3.4, 3.0, 3.5, 3.7,
           3.3, 3.9, 3.2, 3.8, 3.6, 3.8, 3.6, 3.3, 4.0, 3.8, 3.6, 3.6),
  新商品数 = c(9, 6, 15, 8, 10, 6, 7, 4, 16, 9, 14, 10,
           7, 9, 7, 10, 8, 9, 4, 6, 17, 7, 5, 12)
)

# 相関の算出に使う数値列だけを取り出す
wagashi_num <- wagashi[, -1]

# 相関行列を算出して小数点以下2桁に丸める
corr <- round(cor(wagashi_num), 2)

# 算出した相関行列を表示
corr
          来客数 平均単価 月間売上 駅徒歩分  席数 SNS投稿 口コミ点 新商品数
来客数     1.00    -0.01     0.83    -0.90  0.35    0.78     0.18    -0.20
平均単価  -0.01     1.00     0.50    -0.03  0.03    0.04     0.42     0.18
月間売上   0.83     0.50     1.00    -0.74  0.29    0.64     0.33    -0.13
駅徒歩分  -0.90    -0.03    -0.74     1.00 -0.53   -0.68    -0.14     0.02
席数       0.35     0.03     0.29    -0.53  1.00    0.27     0.03     0.08
SNS投稿    0.78     0.04     0.64    -0.68  0.27    1.00     0.48    -0.22
口コミ点   0.18     0.42     0.33    -0.14  0.03    0.48     1.00     0.18
新商品数  -0.20     0.18    -0.13     0.02  0.08   -0.22     0.18     1.00

# 相関係数のp値行列を算出
p_mat <- cor_pmat(wagashi_num)

# p値行列を小数点以下3桁に丸めて表示
round(p_mat, 3)
         来客数 平均単価 月間売上 駅徒歩分  席数 SNS投稿 口コミ点 新商品数
来客数    0.000    0.981    0.000    0.000 0.089   0.000    0.406    0.338
平均単価  0.981    0.000    0.013    0.903 0.873   0.844    0.042    0.398
月間売上  0.000    0.013    0.000    0.000 0.173   0.001    0.113    0.553
駅徒歩分  0.000    0.903    0.000    0.000 0.008   0.000    0.512    0.918
席数      0.089    0.873    0.173    0.008 0.000   0.209    0.881    0.721
SNS投稿   0.000    0.844    0.001    0.000 0.209   0.000    0.016    0.310
口コミ点  0.406    0.042    0.113    0.512 0.881   0.016    0.000    0.392
新商品数  0.338    0.398    0.553    0.918 0.721   0.310    0.392    0.000

相関行列のヒートマップをプロット:ggcorrplotコマンド

オプション意味初期値
corr可視化する相関行列を指定なし
methodセルの描画形状を指定。「square」または「circle」から選択c(“square”, “circle”)
type表示範囲を指定。「full」「lower」「upper」から選択。混合レイアウトでは常に全体を使用c(“full”, “lower”, “upper”)
ggthemeggplot2のテーマ関数またはテーマオブジェクトを指定。混合レイアウトの「number」領域は本オプションの背景色から文字の濃さを決定ggplot2::theme_minimal
titleグラフのタイトルを指定“”
show.legendTRUEで凡例を表示TRUE
legend.title凡例のタイトルを指定“Corr”
show.diag対角成分を表示するかを論理値で指定。NULLの場合はtype = “full”で表示し、「upper」「lower」では非表示NULL
colors塗り分けのグラデーション色を指定。長さ3で低・中・高に対応し、長さ2以上の任意のベクタは等間隔に配置c(“blue”, “white”, “red”)
outline.color正方形や円の輪郭色を指定“gray”
hc.orderTRUEでhclustコマンドによる階層的クラスタリングの順に変数を並び替えFALSE
hc.methodhclustコマンドに渡すクラスター化の手法を指定“complete”
labTRUEで相関係数の数値をプロット上に表示FALSE
lab_col相関係数ラベルの文字色を指定。lab = TRUEのときに有効“black”
lab_size相関係数ラベルの文字サイズを指定。lab = TRUEのときに有効4
lab_fontface相関係数ラベルの書体を指定。「plain」「bold」「italic」「bold.italic」から選択“plain”
sig.starsTRUEかつp.mat指定時、相関係数ラベルに星印を付加。lab = TRUEのときに有効で、閾値は0.001、0.01、0.05に固定されsig.levelの影響を受けないFALSE
p.matp値の行列を指定。NULLの場合はsig.level、insig、pch、pch.col、pch.cexが無効NULL
sig.level有意水準を指定。insig = “pch”の記号の重ね描きと、insig = “blank”の消去の判定に使用0.05
insigp.matの有意性の示し方を指定。「pch」で有意でないセルに記号を重ね、「blank」で有意でないセルを空白にし、「stars」で有意なセルに星印を表示c(“pch”, “blank”, “stars”)
pch有意でないセルに重ねる記号の番号を指定。insig = “pch”のときに有効4
pch.colpchの色を指定。insig = “pch”のときに有効“black”
pch.cexpchのサイズを指定。insig = “pch”のときに有効5
tl.cex変数名ラベルの文字サイズを指定12
tl.col変数名ラベルの文字色を指定。NULLの場合はテーマの色を継承NULL
tl.srt変数名ラベルの回転角度を指定45
tl.vjustx軸の変数名ラベルの垂直方向の位置を指定1
tl.hjustx軸の変数名ラベルの水平方向の位置を指定1
digits相関係数ラベルの小数点以下の表示桁数を指定2
as.is後方互換のために残されたオプション。現在はプロットに影響しないFALSE
nsmall相関係数ラベルの小数点以下の最小桁数を指定。lab = TRUEのときに有効0L
leading.zeroFALSEで相関係数ラベルの先頭のゼロを省略。lab = TRUEのときに有効TRUE
legend.limit塗り分けの色スケールの範囲を長さ2の数値ベクタで指定。NULLでデータの範囲を使用c(-1, 1)
circle.scalemethod = “circle”のときの円の大きさの倍率を指定1
coord.fixedTRUEでcoord_fixedコマンドによりセルを正方形に固定TRUE
lower.method下三角の描画形状を指定。「square」「circle」「number」から選択。指定すると混合レイアウトに切り替わるNULL
upper.method上三角の描画形状を指定。「square」「circle」「number」から選択。指定すると混合レイアウトに切り替わるNULL
hc.rect整数kを指定するとクラスターk個を囲む矩形を描画。hc.order = TRUEかつtype = “full”が必要NULL
palette色覚多様性に配慮した発散配色の名称を指定。「RdBu」または「PuOr」から選択しcolorsより優先NULL
preset出版向けの既定値をまとめて指定。「publication」で白いセル輪郭と「RdBu」配色を適用NULL
hc.rect.colhc.rectで描く矩形の線色を指定。hc.rect指定時に有効“gray30”
scale.squareTRUEかつmethod = “square”のとき、相関の絶対値に応じて正方形の大きさを変化FALSE
cell.gridTRUEで各セルに枠線を描画し、中心を通る格子線を除去FALSE
cell.grid.colcell.gridで描く枠線の色を指定。cell.grid = TRUEのときに有効“grey90”
# 既定の設定で相関行列を正方形のヒートマップ
ggcorrplot(corr)

# 円の大きさで相関の強さを表現し、円をやや大きめに調整
ggcorrplot(corr, method = "circle", circle.scale = 1.2)

# 下三角のみを表示し、変数名の回転角度をゆるやかにする
ggcorrplot(corr, type = "lower", tl.srt = 30, outline.color = "white")

# 似た動きの変数を隣り合わせに並び替え、相関係数を重ねて表示
ggcorrplot(corr, hc.order = TRUE, lab = TRUE, outline.color = "white")

# 並び替えたうえでクラスターを3つに区切り、矩形で囲む
ggcorrplot(corr, hc.order = TRUE, hc.rect = 3, hc.rect.col = "black")

# 相関の絶対値で正方形の大きさを変え、セルを枠線で区切る
ggcorrplot(corr, scale.square = TRUE, cell.grid = TRUE)

# 有意でないセルに記号を重ねる(有意水準は1%)
ggcorrplot(corr, p.mat = p_mat, sig.level = 0.01, pch = 8, pch.col = "gray20")

# 有意でないセルを空白にして、有意な相関だけを残す
ggcorrplot(corr, p.mat = p_mat, insig = "blank", type = "upper")

# 有意なセルに星印だけを描き、有意性のマップとして使う
ggcorrplot(corr, p.mat = p_mat, insig = "stars", lab_size = 5)

# ラベルの先頭のゼロを省き、小数点以下2桁で太字表示
ggcorrplot(corr,
           lab = TRUE, nsmall = 2, leading.zero = FALSE,
           lab_fontface = "bold"
)

# 色覚多様性に配慮した配色に変更し、凡例の見出しを日本語にする
ggcorrplot(corr, palette = "PuOr", legend.title = "相関")

# 下三角を数値、上三角を円にした混合レイアウト
ggcorrplot(corr,
           lower.method = "number", upper.method = "circle",
           show.legend = FALSE
)

コマンド例から一部のプロット結果を紹介

・既定の設定で相関行列を正方形のヒートマップ

・似た動きの変数を隣り合わせに並び替え、相関係数を重ねて表示

・有意でないセルを空白にして、有意な相関だけを残す

[相関係数のp値行列の算出]:cor_pmatコマンド

オプション意味初期値
x数値行列またはデータフレームを指定なし
cor.testコマンドに渡す引数を指定なし
use欠損値を含むペアの扱いを指定。「pairwise.complete.obs」で欠損を除いた組み合わせごとに検定し、「everything」で片方でも欠損があればNAとするc(“pairwise.complete.obs”, “everything”)

順位相関に切り替えると、外れ値の影響を受けにくい判定になります。ここでは平均単価との関係が0.981から0.608へと変化しており、どちらの尺度で評価するかによってp値が変わることが確認できます。

# Pearsonの積率相関係数によるp値のうち、来客数の行だけを表示
round(p_mat["来客数", ], 3)
来客数 平均単価 月間売上 駅徒歩分     席数  SNS投稿 口コミ点 新商品数 
0.000    0.981    0.000    0.000    0.089    0.000    0.406    0.338 

# methodを通じてcor.testコマンドに順位相関の指定を渡す
p_spearman <- cor_pmat(wagashi_num, method = "spearman", exact = FALSE)

# 順位相関でのp値を同じ行だけ表示
round(p_spearman["来客数", ], 3)
来客数 平均単価 月間売上 駅徒歩分     席数  SNS投稿 口コミ点 新商品数 
0.000    0.608    0.000    0.000    0.095    0.000    0.539    0.559 

# 有意水準5%を下回った変数の組み合わせ数を数える
sum(p_mat[upper.tri(p_mat)] < 0.05)
[1] 10

実行例

パッケージのコマンドを組み合わせた、使い方の例です。

有意な相関だけを星印付きで示す発表用の相関マップ

presetで出版向けの既定値をまとめて適用し、有意でないセルを空白にしたうえで、残った相関係数に星印を添えます。並び替えを加えることで、関係の近い変数がまとまって配置されます。

# 配色と白い輪郭をまとめて適用した相関マップ
ggcorrplot(corr,
  # p値行列を渡して有意性の判定に使う
  p.mat = p_mat,
  # 有意でないセルを空白にする
  insig = "blank",
  # 階層的クラスタリングで変数を並び替える
  hc.order = TRUE,
  # 相関係数の数値を重ねて表示する
  lab = TRUE,
  # 相関係数に有意性の星印を付加する
  sig.stars = TRUE,
  # 小数点以下2桁を必ず表示する
  nsmall = 2,
  # 白い輪郭と色覚多様性に配慮した配色を一括指定する
  preset = "publication",
  # 凡例の見出しを日本語にする
  legend.title = "相関",
  # グラフのタイトルを設定する
  title = "和菓子店24店舗における指標間の相関"
)

クラスター構造を矩形で区切って読み解く

hc.rectで指定した数のクラスターを矩形で囲み、scale.squareとcell.gridを組み合わせることで、相関の強さを色と大きさの両方で表現します。どの変数群が同じ動きをしているかを、対角のブロックとして読み取れます。

# 相関の強さを色と正方形の大きさの両方で表す相関マップ
ggcorrplot(corr,
  # クラスタリング順に並び替える(hc.rectの利用に必須)
  hc.order = TRUE,
  # クラスターを3つに分けて矩形で囲む
  hc.rect = 3,
  # 矩形の線色を黒にして境界を目立たせる
  hc.rect.col = "black",
  # 相関の絶対値に応じて正方形の大きさを変える
  scale.square = TRUE,
  # セルごとに枠線を描いて位置を追いやすくする
  cell.grid = TRUE,
  # セルの枠線をやや濃いグレーにする
  cell.grid.col = "grey80",
  # 正方形の大きさの範囲を広げる
  circle.scale = 1.3,
  # 変数名を回転させずに水平に表示する
  tl.srt = 0,
  # x軸の変数名をセルの中央にそろえる
  tl.hjust = 0.5
)

欠損値を含むデータでp値行列の欠損パターンをそろえる

useを切り替えると、cor_pmatコマンドがNAを返すセルの範囲が変わります。corコマンドの結果と欠損の位置をそろえたい場合は「everything」を指定します。

「pairwise.complete.obs」では欠損を除いた組み合わせで検定可能なのでNAは生じません。「everything」では欠損を含む変数が関わる26がNAとなり、corコマンドの結果と欠損の位置が一致します。

# 欠損値を含むデータを作成
wagashi_na <- wagashi_num

# SNS投稿の3行目を欠損にする
wagashi_na[3, "SNS投稿"] <- NA

# 口コミ点の8行目を欠損にする
wagashi_na[8, "口コミ点"] <- NA

# 欠損を除いた組み合わせごとに検定する既定の挙動
p_pairwise <- cor_pmat(wagashi_na)

# NAとなったセル数を数える
sum(is.na(p_pairwise))
[1] 0

# 片方でも欠損があればNAとする挙動に切り替える
p_everything <- cor_pmat(wagashi_na, use = "everything")

# NAとなったセル数を数える
sum(is.na(p_everything))
[1] 26

# corコマンドの欠損パターンと一致していることを確認
sum(is.na(cor(wagashi_na)))
[1] 26


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。