18

標準の箱ひげ図が非常に混雑しているように見える十分なグループに分割したデータがいくつかあります。Tufte には、次のように、基本的にボックスのすべてまたは半分をドロップする独自のボックスプロットがあります。

タフト箱ひげ図

いくつかのサンプルデータ:

cw <- transform(ChickWeight, 
  Time = cut(ChickWeight$Time,4)
  )
cw$Chick <- as.factor( sample(LETTERS[seq(3)], nrow(cw), replace=TRUE) )
levels(cw$Diet) <- c("Low Fat","Hi Fat","Low Prot.","Hi Prot.")

食事 * 時間 * ひよこグループごとに体重の箱ひげ図が必要です。

この問題は何年も前に発生し、グリッド グラフィックスを使用して解決策をまとめました。これについては、後で投稿します。しかし、この新しい(そして同様の)問題を解決する際に、私のまとまりのない例を修正するのではなく、それらを行うための標準的な方法があるかどうか疑問に思っています。

余談ですが、これらは Tufte の作品の中であまり愛されていないように見えますが、多数のグループにまたがる分布のパターンを密に表示する点で非常に気に入っています。 ggplot2 または格子。

4

5 に答える 5

18

parsこれは、パッケージを使用せずに、ボックスプロットのグラフィカルパラメーターを操作するだけのソリューションです。私の提案は @DWin に最も近いものですが、色と軸を取り除き、数行のコードしか使用しません。@gsk3 と @Ramnath による両方の提案は非常に優れており、私のものよりもはるかに進んでいますが、私がコメントする場合、それらは Tufte の主要な哲学に対応していません。灰色の背景、白い「刑務所バー」、および不要な色を取り除くと、上記のすべてのソリューションが明確さ、シンプルさ、および適切なデータとインクのバランスを得ることができます.

クレジットは、Tufte の作品にインスパイアされたPerformanceAnalyticsかわいいラッパーを含むの作成者に送られる必要があります。chart.Boxplot関数のいくつかの要素を抽出して、さらにシンプルにしています。@gsk3 から上記の 'cw' サンプル データを添付するだけです。

attach(cw)
par(mfrow=c(1,3))
boxplot(weight~Time, horizontal = F, main = "", xlab="Time", ylab="Weight", 
        pars = list(boxcol = "white", medlty = "blank", medpch=16, medcex = 1.3, 
        whisklty = c(1, 1), staplelty = "blank", outcex = 0.5), axes = FALSE)
axis(1,at=1:4,label=c(1:4))
axis(2)
boxplot(weight~Chick, horizontal = F, main = "", xlab = "Chick", 
        ylab = "", pars = list(boxcol = "white", medlty = "blank", medpch=16, 
        medcex = 1.3, whisklty = c(1, 1), staplelty = "blank", outcex = 0.5), 
        axes = FALSE)
axis(1,at=1:3,label=c("A","B","C"))
boxplot(weight~Diet, horizontal = F, main = "", xlab = "Diet", ylab = "", 
        pars = list(boxcol = "white", medlty = "blank", medpch=16, medcex = 1.3, 
        whisklty = c(1, 1), staplelty = "blank", outcex = 0.5), axes = FALSE)
axis(1,at=1:4,label=c("LoFat","HiFat","LoProt","HiProt"))

ここに画像の説明を入力

于 2011-11-28T20:57:36.237 に答える
15

どうやら垂直バージョンだけが必要だったので、panel.bwplot コードを使用して、ボックスやキャップなどの重要でないものをすべて取り除き、引数に horizo​​ntal=FALSE を設定して、panel.tuftebxp 関数を作成しました。また、ポイントの cex をデフォルトの半分に設定します。好みに合わせて調整できるオプションがまだかなり残っています。「時間」の「数値」要素名は雑に見えますが、「概念実証」は明確であり、重要なものをクリーンアップできると思います。

panel.tuftebxp <- 
function (x, y, box.ratio = 1, box.width = box.ratio/(1 + box.ratio), horizontal=FALSE,
    pch = box.dot$pch, col = box.dot$col, 
    alpha = box.dot$alpha, cex = box.dot$cex, font = box.dot$font, 
    fontfamily = box.dot$fontfamily, fontface = box.dot$fontface, 
    fill = box.rectangle$fill, varwidth = FALSE, notch = FALSE, 
    notch.frac = 0.5, ..., levels.fos = if (horizontal) sort(unique(y)) else sort(unique(x)), 
    stats = boxplot.stats, coef = 1.5, do.out = TRUE, identifier = "bwplot") 
{
    if (all(is.na(x) | is.na(y))) 
        return()
    x <- as.numeric(x)
    y <- as.numeric(y)
    box.dot <- trellis.par.get("box.dot")
    box.rectangle <- trellis.par.get("box.rectangle")
    box.umbrella <- trellis.par.get("box.umbrella")
    plot.symbol <- trellis.par.get("plot.symbol")
    fontsize.points <- trellis.par.get("fontsize")$points
    cur.limits <- current.panel.limits()
    xscale <- cur.limits$xlim
    yscale <- cur.limits$ylim
    if (!notch) 
        notch.frac <- 0
    #removed horizontal code
     blist <- tapply(y, factor(x, levels = levels.fos), stats, 
            coef = coef, do.out = do.out)
        blist.stats <- t(sapply(blist, "[[", "stats"))
        blist.out <- lapply(blist, "[[", "out")
        blist.height <- box.width
        if (varwidth) {
            maxn <- max(table(x))
            blist.n <- sapply(blist, "[[", "n")
            blist.height <- sqrt(blist.n/maxn) * blist.height
        }
        blist.conf <- if (notch) 
            sapply(blist, "[[", "conf")
        else t(blist.stats[, c(2, 4), drop = FALSE])
        ybnd <- cbind(blist.stats[, 3], blist.conf[2, ], blist.stats[, 
            4], blist.stats[, 4], blist.conf[2, ], blist.stats[, 
            3], blist.conf[1, ], blist.stats[, 2], blist.stats[, 
            2], blist.conf[1, ], blist.stats[, 3])
        xleft <- levels.fos - blist.height/2
        xright <- levels.fos + blist.height/2
        xbnd <- cbind(xleft + notch.frac * blist.height/2, xleft, 
            xleft, xright, xright, xright - notch.frac * blist.height/2, 
            xright, xright, xleft, xleft, xleft + notch.frac * 
                blist.height/2)
        xs <- cbind(xbnd, NA_real_)
        ys <- cbind(ybnd, NA_real_)
        panel.segments(rep(levels.fos, 2), c(blist.stats[, 2], 
            blist.stats[, 4]), rep(levels.fos, 2), c(blist.stats[, 
            1], blist.stats[, 5]), col = box.umbrella$col, alpha = box.umbrella$alpha, 
            lwd = box.umbrella$lwd, lty = box.umbrella$lty, identifier = paste(identifier, 
                "whisker", sep = "."))

        if (all(pch == "|")) {
            mult <- if (notch) 
                1 - notch.frac
            else 1
            panel.segments(levels.fos - mult * blist.height/2, 
                blist.stats[, 3], levels.fos + mult * blist.height/2, 
                blist.stats[, 3], lwd = box.rectangle$lwd, lty = box.rectangle$lty, 
                col = box.rectangle$col, alpha = alpha, identifier = paste(identifier, 
                  "dot", sep = "."))
        }
        else {
            panel.points(x = levels.fos, y = blist.stats[, 3], 
                pch = pch, col = col, alpha = alpha, cex = cex, 
                 identifier = paste(identifier, 
                  "dot", sep = "."))
        }
        panel.points(x = rep(levels.fos, sapply(blist.out, length)), 
            y = unlist(blist.out), pch = plot.symbol$pch, col = plot.symbol$col, 
            alpha = plot.symbol$alpha, cex = plot.symbol$cex*0.5, 
            identifier = paste(identifier, "outlier", sep = "."))

}
bwplot(weight ~ Diet + Time + Chick, data=cw, panel= 
         function(x,y, ...) panel.tuftebxp(x=x,y=y,...))

ここに画像の説明を入力

于 2011-08-07T15:46:33.173 に答える
11

これが通常のggplot解決策です(または、優雅さの範囲を備えたハック)

require(ggplot2)

# melt the data frame
cw2 = melt(cw, id = 'weight')

# create a data frame with boxplot stats
cw3 = ddply(cw2, .(value, variable), function(df) boxplot.stats(df$weight)$stats)

# generate the plot
ggplot(cw2, aes(value, weight)) +
  geom_boxplot(fill = 'gray90', colour = 'gray90', alpha = 0) +      
  geom_segment(data = cw3, aes(xend = value, y = V1, yend = V2)) + 
  geom_segment(data = cw3, aes(xend = value, y = V4, yend = V5)) + 
  geom_point(data = cw3, aes(y = V3), size = 3) + 
  facet_wrap(~ variable, scales = 'free_x', nrow = 1)      

ここに画像の説明を入力

于 2011-08-07T16:53:46.510 に答える
8

これが私の非常に厄介な機能です。残念ながら、このコードは panel.tuftebox を参照していますが、R を学習し始めて最初の数か月で非常に特定の目的で (したがって、悲しいことに、一般化する意図はありませんでした)、このコードを書いたため、別のコードとして書かれることはありませんでした。パネル機能。

library(lattice)
library(taRifx)
compareplot(~weight | Diet * Time * Chick, 
  data.frame=cw , 
  main = "Chick Weights",
  box.show.mean=FALSE,
  box.show.whiskers=FALSE,
  box.show.box=FALSE
  )

比較プロット

于 2011-08-07T15:57:22.370 に答える
7

githubで利用可能な、JeffreyArnoldggthemesによるパッケージにいくつかのタフテスタイルのプロットを作成するための関数があります。このパッケージは、次のテーマの集まりであり、次のものが含まれます。ggplot

geom_tufterangeframe:タフテのレンジフレーム

geom_tufteboxplot:タフテの箱ひげ図

theme_tufte:タフテの定量的情報の視覚的表示に基づく最小限のインク。

github上のパッケージのREADMEからのTufte最小箱ひげ図の例を次に示します。

ここに画像の説明を入力してください

于 2013-01-01T19:24:12.173 に答える