ggplotを使用して外れ値のないボックスプロットをプロットし、ボックスとウィスカーのみに焦点を当てたい
例えば:
p1 <- ggplot(diamonds, aes(x=cut, y=price, fill=cut))
p1 + geom_boxplot() + facet_wrap(~clarity, scales="free")
外れ値を含むファセットボックスプロットを表示します
outlier.size=NA で外れ値を抑制できます:
p1 <- ggplot(diamonds, aes(x=cut, y=price, fill=cut))
p1 + geom_boxplot(outlier.size=NA) + facet_wrap(~clarity, scales="free")
これにより
ここで、y 軸のスケールは元のプロットと同じですが、外れ値が表示されません。ヒゲの端に応じて各パネルを「ズームイン」するようにスケールを変更するにはどうすればよいでしょうか。
このようにylimをリセットできます
ylim1 = boxplot.stats(diamonds$price)$stats[c(1, 5)]
そして再プロット
p1 + geom_boxplot(outlier.size=NA)
+ facet_wrap(~clarity, scales="free")
+ coord_cartesian(ylim = ylim1*1.05)
しかし、これはファセットでは機能しません:
boxplots.stats 関数を「facet_wrap」する方法はありますか?
編集:
ボックスプロットの統計を動的に計算しようとしましたが、うまくいかないようです。
give.stats <- function(x){return(boxplot.stats(x)$stats[c(1,5)])}
p1 + geom_boxplot(outlier.size=NA) +
facet_wrap(~clarity, scales="free") +
coord_cartesian(ylim = give.stats)
> Error in min(x, na.rm = na.rm) : invalid 'type' (list) of argument
他に何かアイデアがあれば、ぜひ教えてください。
ベストアンサー1
これは、stat_summary とカスタム統計計算関数を使用して実行できます。
calc_boxplot_stat <- function(x) {
coef <- 1.5
n <- sum(!is.na(x))
# calculate quantiles
stats <- quantile(x, probs = c(0.0, 0.25, 0.5, 0.75, 1.0))
names(stats) <- c("ymin", "lower", "middle", "upper", "ymax")
iqr <- diff(stats[c(2, 4)])
# set whiskers
outliers <- x < (stats[2] - coef * iqr) | x > (stats[4] + coef * iqr)
if (any(outliers)) {
stats[c(1, 5)] <- range(c(stats[2:4], x[!outliers]), na.rm = TRUE)
}
return(stats)
}
ggplot(diamonds, aes(x=cut, y=price, fill=cut)) +
stat_summary(fun.data = calc_boxplot_stat, geom="boxplot") +
facet_wrap(~clarity, scales="free")
統計計算関数は汎用的であるため、プロットする前にデータを操作する必要はありません。
ウィスカーを10%と90%に設定することも可能です。
calc_stat <- function(x) {
coef <- 1.5
n <- sum(!is.na(x))
# calculate quantiles
stats <- quantile(x, probs = c(0.1, 0.25, 0.5, 0.75, 0.9))
names(stats) <- c("ymin", "lower", "middle", "upper", "ymax")
return(stats)
}
ggplot(diamonds, aes(x=cut, y=price, fill=cut)) +
stat_summary(fun.data = calc_stat, geom="boxplot") +
facet_wrap(~clarity, scales="free")