目的 群別のデータ点を記号で描く 使用法 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") 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]) 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) 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]) pch = "." とすると,目立たないがデータがたくさんあるときにはいいかもしれない dot.plot(iris$Species, iris$Petal.Length, accu=0.1, stp=0.05, xlab="Species", ylab="Petal Length", main="iris data", pch=".") 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)]) 左は通常目盛りで描き,右は同じデータを対数目盛りで描いた。 それぞれの群において,データは対数正規分布に従うように作られた。