群別データ分布図     Last modified: Oct 12, 2004

目的

群別のデータ点を記号で描く

使用法

dot.plot(x, y, accu=0, stp=0, log.flag=FALSE, simple=FALSE, symmetrical=TRUE, ...)

引数

x            群を表す変数の値ベクトル(factor でも,numeric でもよい)
y            分布を調べる対象変数の数値ベクトル
accu         y を階級化するための値。
             階級幅ということになるが,記号が重ならないようにするには,大き目の値を設定するとよい
stp          水平方向に記号を並べるときに,記号が重ならないようにずらすための値
log.flag     対数目盛りで描くときに TRUE を指定する(省略時には FALSE になっており,普通の目盛りで描く)
simple       対数目盛りで描くときに,目盛り数字を 10 のべき乗に限る(0.1, 1, 10, 100 などのみ)ならば TRUE にする
symmetrical  描画する記号を左右対称にせず,ヒストグラム風にするとき FALSE にする
...          plot 関数が受け付ける任意の引数(使用例を参照)

注:accu と stp は対話的に決める方がよい。最初は指定せずに描き,出力された accu と stp の値を参考に調整する。

ソース

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

# 群別のデータプロット
dot.plot <- function(        x,                                              # 群変数ベクトル
                        y,                                              # データベクトル
                        accu=0,                                         # データを階級化するための値
                        stp=0,                                          # 水平方向に記号を並べるときのずらす量
                        log.flag=FALSE,                                 # 縦軸を対数目盛りにするとき TRUE
                        simple=FALSE,                                   # 対数目盛りのとき,目盛数値を 10 のべき乗に限るなら TRUE
                        symmetrical=TRUE,                               # 記号を左右対称にするなら TRUE
                        ...)                                            # plot 関数に引き渡すその他の引数
{
        OK <- complete.cases(x, y)                                   # 欠損値を持つケースを除く
        x <- x[OK]
        y <- y[OK]
        x.name <- unique(x)                                          # 群を表す変数の取る値(factor でありうる)
        if (is.factor(x)) {                                             # factor なら,
                x <- as.integer(x)                                   # 整数値に戻す
        }
        if (log.flag == TRUE) {                                         # 対数目盛りで描くなら,
                y0 <- y                                                      # 値のバックアップをとってから,
                y <- log10(y)                                                # 常用対数をとる
        }
        if (accu == 0) {                                                # accu のデフォルト値を計算
                accu <- diff(range(y))/100                           # 最大値と最小値の差の百分の一
        }
        if(stp == 0) {                                                  # spt のデフォルト値を計算
                stp <- diff(range(x))/100                            # 最大値と最小値の差の百分の一
        }
        y <- round(y/accu)*accu                                              # y を丸める
        x1 <- unique(x)                                                      # 群を表す変数の種類(数値に変換したもの)
        for (i in seq(along=x1)) {                                      # 全ての群について,
                freq <- table(y[x==x1[i]])                           # ある群のデータについて度数分布を求める
                for (j in seq(along=freq)) {                            # 度数分布の各階級について
                        if (freq[j] >= 2) {                             # 複数個のデータがあるならば,
                                offset <- ifelse(symmetrical, (freq[j]-1)/2*stp, 0)  # 対称に描くかどうかで描き始めが違う
                                for (k in seq(along=y)) {
                                        if (abs(y[k]-as.numeric(names(freq)[j])) < 1e-10 && abs(x[k]-x1[i]) < 1e-10) {
                                                freq[j] <- freq[j]-1
                                                x[k] <- x[k]-offset+freq[j]*stp
                                        }
                                }
                        }
                }
        }
        if (log.flag) {                                                 # 対数目盛りで描くなら,
                plot(x, y, type="n", xaxt="n", yaxt="n", ...)
                options(warn=-1)
                points(x, y, ...)
                options(warn=0)
                y0 <- floor(log10(y0))
                log.min <- min(y0)
                y2 <- 1:10*10^log.min
                n <- max(y0)-log.min
                y1 <- rep(y2, n+1)*10^rep(0:n, each=10)
                if (simple) {
                        y2 <- y1[abs(log10(y1)-round(log10(y1))) < 1e-6]
                        axis(2, at=log10(y1), labels=FALSE)
                        axis(2, at=log10(y2), labels=y2)
                }
                else {
                        axis(2, at=log10(y1), labels=y1)
                }
        }
        else {
                plot(x, y, xaxt="n", ...)
        }
        axis(1, at=x1, labels=as.character(x.name))
        print(paste("accu =", accu, "   stp = ", stp), quote=FALSE)
}


使用例

data(iris)	# Fisher の iris data を,種別に図示してみる

dot.plot(iris$Species, iris$Petal.Length, accu=0.1, stp=0.05, xlab="Species", ylab="Petal Length", main="iris data")

graph

col により色を変える

g <- as.integer(iris$Species)
dot.plot(iris$Species, iris$Petal.Length, accu=0.1, stp=0.05, xlab="Species", ylab="Petal Length", main="iris data", col=c("blue", "brown", "red")[g])

graph

pch により,記号を変える

dot.plot(iris$Species, iris$Petal.Length, accu=0.1, stp=0.05, xlab="Species", ylab="Petal Length", main="iris data", col=c("blue", "brown", "red")[g], pch=g)

graph

pch により,アルファベットなどで描くこともできる

dot.plot(iris$Species, iris$Petal.Length, accu=0.2, stp=0.1, xlab="Species", ylab="Petal Length", main="iris data", pch=letters[g])

graph

pch = "." とすると,目立たないがデータがたくさんあるときにはいいかもしれない

dot.plot(iris$Species, iris$Petal.Length, accu=0.1, stp=0.05, xlab="Species", ylab="Petal Length", main="iris data", pch=".")

graph

log.flag = TRUE により,対数目盛りのグラフにすることもできる

set.seed(111)
x <- factor(rep(paste("Group", LETTERS[1:5], sep="-"), each=50))
y <- rnorm(250)+rep(1:5/5, each=50)
y <- exp((y-min(y)+1))
dot.plot(x, y, accu=40, stp=0.065, col=c("black", "red", "blue", "brown", "purple")[as.integer(x)])
dot.plot(x, y, log.flag=TRUE, accu=0.07, stp=0.065, col=c("black", "red", "blue", "brown", "purple")[as.integer(x)])
左は通常目盛りで描き,右は同じデータを対数目盛りで描いた。
それぞれの群において,データは対数正規分布に従うように作られた。

graph graph
simple = TRUE により,対数目盛りのラベルを簡略化する graph symmetrical = FALSE により,ヒストグラム風になる(左右対称にしない) graph


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

Made with Macintosh