散布図・箱髭図の描画     Last modified: Dec 12, 2012

目的

二変数の散布図またはグループ別一変量ボックスプロット(箱髭図)を描く。

使用法

twodim.plot(i, j, df, lm=TRUE, cor=c("none", "pearson", "kendall", "spearman"),
            digits=3, plot="", type=c("pdf", "png", "jpeg", "bmp", "tiff"),
            width=500, height=375, xlab=NULL, ylab=NULL)

引数

i       x 軸にとる変数のデータフレーム上での列番号または変数名(ベクトルとして複数指定可)
j       y 軸にとる変数のデータフレーム上での列番号または変数名(ベクトルとして複数指定可)
        x 軸にとる変数か y 軸にとる変数の何れかが factor のときはボックスプロット図
        x 軸にとる変数と y 軸にとる変数のどちらも数値変数のときは散布図
        i, j のすべての組み合わせで作図する
df      読み込んだデータフレームの名前
lm      回帰直線を描き込むときに TRUE(デフォルトは FALSE)
cor     散布図を描き相関係数を計算し描き込むときに"pearson", "kendall", "spearman" の何れかを指定する
        それぞれ,ピアソンの積率相関係数,ケンドールの順位相関係数,スピアマンの順位相関係数を指定する
        描き込まないときは none(デフォルト)
digits  相関係数を描き出すときに小数点以下何桁までにするかを指定
        デフォルトでは 3
plot    散布図を出力するファイルの名前
        複数のグラフが出力されるときは実際には「名前001.pdf],「名前002.pdf]のように連番のファイル名になる
        デフォルトでは空文字列("")で,そのときはグラフを出力しない
type    画像ファイルのフォーマットを "pdf", "png", "jpeg", "bmp", "tiff" から指定する。デフォルトは "pdf"
        Macintoshの場合,"png", "jpeg", "bmp", "tiff" を選ぶ場合には,事前に X11 を起動しておかなければならない。
width   画像の横幅のピクセル数(デフォルトは 500 ピクセル)
height  画像の高さのピクセル数(デフォルトは 375 ピクセル)
xlab    横軸のラベル(デフォルトはデータフレームでの変数名)
ylab    縦軸のラベル(デフォルトはデータフレームでの変数名)

ソース

インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/twodim-plot.R", encoding="euc-jp")

#####
#
# 分析対象変数が,共に数値変数である場合には散布図,何れかが factor である場合には箱髭図を描く
#
#####

twodim.plot <- function(i,                                                   # x 軸に取る変数が入っているデータフレーム上の列番号または変数名ベクトル
                        j,                                                      # y 軸に取る変数が入っているデータフレーム上の列番号または変数名ベクトル
                        df,                                                     # データフレーム
                        k=NULL,                                                 # もしあれば,群を表す変数(factor)が入っているデータフレーム上の列番号または変数名ベクトル
                        lm=FALSE,                                               # 回帰直線を描き込むとき TRUE にする(デフォルト FALSE では,描き入れない)
                        cor=c("none", "pearson", "kendall", "spearman"),        # 計算する相関係数を指定する(デフォルト none では,計算しない)
                        digits=3,                                               # 相関係数の小数点以下の桁数
                        plot="",                                                # 散布図を描き出すファイル名(デフォルトは Quarts デバイスに出力)
                        type=c("pdf", "png", "jpeg", "bmp", "tiff"),            # 画像フォーマット(plot と併せてファイル名の拡張子として使う)
                        width=500,                                              # 画像の横幅のピクセル数(デフォルトは500ピクセル)
                        height=375,                                             # 画像の高さのピクセル数(デフォルトは375ピクセル)
                        xlab=NULL,                                              # x 軸のラベル(デフォルトは対象変数名)。何も描かないときには空文字列を指定する
                        ylab=NULL,                                              # y 軸のラベル(デフォルトは対象変数名)。何も描かないときには空文字列を指定する
                        ...)                                                    # 作図関数に渡されるその他の引数
{
        twodim.plot2 <- function(i, j, k)                                    # 下請け関数。i, j はスカラー
        {
                if (is.null(k)) {
                        df2 <- df[, c(i, j)]                                 # データフレームの列番号 i, j から 2 変数を取り出す
                }
                else {
                        if (is.character(k[1])) {
                                k <- getNum(k, df)
                        }
                        df2 <- df[, c(i, j, k )]
                }
                df2 <- subset(df2, complete.cases(df2))                              # 欠損値を持つケースを除く
                xlab2 <- if (is.null(xlab)) colnames(df2)[1] else xlab               # x 軸のラベルが指定されていないときには変数名を使う
                ylab2 <- if (is.null(ylab)) colnames(df2)[2] else ylab               # y 軸のラベルが指定されていないときには変数名を使う
                if (is.factor(df2[,1]) && is.factor(df2[,2])) {                   # 2 変数ともに数値変数でない場合にはエラー
                        cat(i, "列と", j, "列の変数は,共に数値変数ではありません\n")
                }
                else if (is.numeric(df2[,1]) && is.numeric(df2[,2])) {            # 2 変数ともに数値変数の場合には,散布図(および回帰直線など)を描く
                        if (is.null(k)) {
                                pch <- 1
                        }
                        else {
                                pch <- as.integer(df2[,3])
                        }
                        plot(df2[,1], df2[,2], xlab=xlab2, ylab=ylab2,          # まずは散布図を描く
                             pch=pch, ...)
                        method.name <- switch(cor,                           # 引数 cor と変数 method.name の対応付け
                                                none = "",
                                                pearson = "ピアソンの積率相関係数",
                                                kendall = "ケンドールの順位相関係数",
                                                spearman = "スピアマンの順位相関係数")
                        if (method.name == "") {                                # 相関係数が不要なら,
                                r <- ""                                              # r は空
                        }
                        else {                                                  # 3種の相関係数の何れかを計算し,r に文字列として設定する
                                r <- paste(method.name, "=", sprintf(format, cor(df2, use="pairwise.complete.obs", method=cor)[1,2]), sep="")
                        }
                        if (lm) {                                               # 回帰直線を描き込むなら,
                                ans <- lm(df2[,2]~df2[,1])                   # 直線回帰分析を行い,
                                abline(ans)                                     # 散布図に回帰直線を描き込み,切片・傾きを str に文字列として設定する
                                str <- paste("切片=", sprintf("%g", ans$coefficients[1]), " 傾き=", sprintf("%g", ans$coefficients[2]), sep="")
                        }
                        else {
                                str <- ""                                    # 回帰直線を描き込まないなら,str は空
                        }
                        if (r != "" || str != "") {                             # 相関係数,または,切片・傾きを書き込むときには,
                                str <- paste(r, str, sep=" ")                       # 両方の結果を str に設定する
                                rangex <- range(df2[,1])                     # x 軸に取った変数の範囲を求める
                                rangey <- range(df2[,2])                     # y 軸に取った変数の範囲を求める
                                old <- par(xpd=TRUE)                         # プロット領域の外にも描き込めるように設定
                                text(mean(rangex), 1.1*rangey[2]-0.1*rangey[1], # 適当な位置に str を描く
                                     str, pos=3, ...)
                                par(old)                                        # 元に戻す
                        }
                }
                else if (is.factor(df2[,1]) && is.numeric(df2[,2])) {             # i 列の変数が factor で,j 列の変数が数値変数なら,
                        boxplot(df2[,2]~df2[,1], xlab=xlab2, ylab=ylab2, ...)   # 垂直な boxplot を描く
                }
                else if (is.numeric(df2[,1]) && is.factor(df2[,2])) {             # i 列の変数が数値変数で,j 列の変数が factor なら,
                        boxplot(df2[,1]~df2[,2], xlab=xlab2, ylab=ylab2,        # 水平な boxplot を描く
                                horizontal=TRUE, ...)
                }
        }
        getNum <- function(str, df) {                                                # 変数名から列番号を得る
                names <- colnames(df)
                seq_along(names)[names %in% str]
        }
# twodim.plot 関数本体
        cor <- match.arg(cor)                                                        # 引数で短縮形で指定された場合にも cor を正式なものに設定する
        format <- paste("%.", digits, "f", sep="")                           # 相関係数の小数点以下の桁数を設定する
        if (plot != "") {                                                       # グラフをファイルに出力するとき plot はファイル名(拡張子を除く)
                type <- match.arg(type)                                              # 画像ファイルの形式
                if (type == "pdf") {                                            # pdf なら,一つ一つの画像を別々のファイルに出力するために onefile = FALSE にする
                        pdf(sprintf("%s%%03i.pdf", plot), onefile=FALSE,        # pdf は,画像の大きさの指定がインチ単位なので 72dot/inch で換算
                            width=width/72, height=height/72)
                }
                else if (type == "png") {
                        png(sprintf("%s%%03i.%s", plot, type), width=width, height=height)
                }
                else if (type == "bmp") {
                        bmp(sprintf("%s%%03i.%s", plot, type), width=width, height=height)
                }
                else if (type == "jpeg") {
                        jpeg(sprintf("%s%%03i.%s", plot, type), width=width, height=height)
                }
                else { # type == "tiff"
                        tiff(sprintf("%s%%03i.%s", plot, type), width=width, height=height)
                }
        }
        if (is.character(i[1])) {
                i <- getNum(i, df)
        }
        if (is.character(j[1])) {
                j <- getNum(j, df)
        }
        for (ii in i) {
                for (jj in j) {
                        if (ii != jj) {
                                twodim.plot2(ii, jj, k)                         # 第 1,第 2 引数の全ての組み合わせで図を描くために twodim.plot2 を呼ぶ
                        }
                }
        }
        if (plot != "") {                                                       # ファイルに出力しているなら,
                dev.off()                                                       # デバイスを閉じる
        }
}


使用例

set.seed(12345)
df <- data.frame(matrix(rnorm(100), 20))
df[,5] <- factor(sample(5, 20, replace=TRUE),levels=1:5, labels=LETTERS[1:5])
twodim.plot(1, 2:3, df, lm=TRUE, cor="pearson", plot="scatter")
twodim.plot(5, 2:4, df, plot="boxplot")

出力結果例

graph

graph


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI

Made with Macintosh