Memo plus Alpha

メモにプラスアルファを加えて価値ある情報に。

Rの対応分析でラベルの重なりを解消する

はじめに

Rで対応分析を行う場合、変数が多いとラベルが重複してしまう可能性があります。その場合、plot関数だけではうまく処理できません。

地道なやり方としてはメタファイルに出力して、Adobe Illustratorなどで処理することも可能ですが、ここではwordcloudライブラリを使った方法をメモしておきます(参考:wordcloud makes words less cloudy « Fells Stats)。

 

用意するもの

  • R(できるだけ最新版を)
  • MASSライブラリをインストール
  • wordcloudライブラリをインストール
  • 分析するデータ

→ここでは次のデータ(部分抜粋。単語は38行あります。A~Eはジャンルだと考えてください)を処理します。

f:id:semanticist:20160212114046p:plain

plotしてみる

MASSライブラリを読み込み、corresp関数で対応分析を実行しplotします。

>library(MASS)
>words=read.table("clipboard",header=T)
> words.corresp=corresp(words,nf=4)
> plot(words.corresp)

 

20160210205851

 これだとかなり重なりがあり、可読性が低い状態です。

 

予備知識

オブジェクト型はclass関数で見ることができます。

> class(words.corresp)
[1] "correspondence"

correspondence型は$cscoreで列側(上のデータではA、B、C、D、E)のスコアに、$rscoreで行側(単語)にアクセスできます。

例えば:

 > words.corresp$cscore
[,1] [,2] [,3] [,4]
A 3.6911623 1.6803089 0.1717679 0.03243607
B 0.9217827 -2.6917578 0.7224602 -0.10977487
C -0.1368556 -0.1294318 -1.6574275 0.22612367
D -0.4579921 0.3830560 0.4693191 -1.04030145
E -0.4899167 0.3618963 0.8463817 1.69203612

となります。

 

また、$corで相関係数を表示します。

> words.corresp$cor
[1] 0.57024044 0.20068781 0.14170275 0.08328265

 

$cor[1]が第1主成分の相関係数、$cor[2]が第2主成分の相関係数です。

Rのplot関数は、2つの系列のスコア($cscoreと$rscore)を同時に配置するために、それぞれの固有値を相関係数で重み付けをしています。

例えば、Aの第1主成分3.69は(X軸)、第1主成分の相関係数0.57を乗じてプロットされます。

このとき、plot関数で作成される座標軸のスケールにも注意が必要です。図中、上と右に記されるのがrscoreの系統、下と左にあるのがcscoreの系統です。原点だけ一致しています(この見え方はwordcloudを使うと軸を固定することになるので少し変わります)。

 

wordcloudを使う

ではwordcloudを使って描写してみましょう。この関数はそもそもワードクラウドを作成するためものです。

semanticist.hatenablog.com

 

しかしながら、texplot関数という大変良くできたものを含んでおり、これを使うことでラベルの重なりを解消することができます。

考え方としては、rscoreとcscoreをtextplot関数で同一画面に上書きで作画する、ということです。このとき、座標軸を固定するのがポイントです。そのためにはxlimとylim(軸の最小値と最大値)を同じにする必要があります。

動的にも取得できますが、先ほどのbiplotをみて決めるのが楽だと思います。今回はxlim=c(-1.5,3),ylim=c(-1.5,2)で固定します。

 

textplot関数は第1引数にXの値を、第2引数にYの値を、第3引数にラベルを取ります。

 

まず、ライブラリを読み込みます。

>library(wordcloud)

 

行と列、それぞれのスコアを変数に格納します。

> words.corresp.rscore=words.corresp$rscore
> words.corresp.cscore=words.corresp$cscore

 

rscore(単語の方)からプロットしてみましょう。

>textplot(words.corresp.rscore[,1]*words.corresp$cor[1],

words.corresp.rscore[,2]*words.corresp$cor[2],rownames(words.corresp.rscore),

xlim=c(-1.5,3),ylim=c(-1.5,2))

 

ここで*words.corresp$cor[1]を乗じているのは、重み付けのためです。つまり、words.corresp.rscore[,1]*words.corresp$cor[1]は第1主成分の列に相関係数を乗じて座標点を計算する、という意味になります。第2主成分も同様です。

20160210205955

だいぶきれいに描画できました。

では、ここにcscoreのほうも重ねてみましょう。グラフを上書きするにはpar(new=T)を指定しいます。

> par(new=T)

 

次いでtextplotを行います。xlimとylimを同じにすることを忘れずに。

>textplot(words.corresp.cscore[,1]*words.corresp$cor[1],

words.corresp.cscore[,2]*words.corresp$cor[2],rownames(words.corresp.cscore),

xlim=c(-1.5,3),ylim=c(-1.5,2), col="blue", font=2)

色は青(col="blue")、そして太字(font=2)にしています。

20160210210002

まとめ

対応分析をplotするとラベルが重なることがある

wordcloudライブラリのtextplotを使うと自動的に重なりを調整してくれる

引数を渡すには$cscore, $rscore, rownames関数を使って値を取得する。その際、$corで重み付けをする