我正在尝试使用ggplot2绘制boxplot。我想将中间意思改为。
我知道人们以前也曾问过类似的问题,但是我问这个是因为解决方案对我不起作用。具体来说,我遵循了这个公认的answer
中的第一个解决方案这是我对mpg测试数据所做的:
library(ggplot2)
library(tidyverse)
mpg %>%
ggplot(aes(x = class, y = cty, middle = mean(cty))) +
geom_boxplot()
它无效。
任何人都可以指出我做错了什么吗?谢谢。
答案 0 :(得分:1)
在另一个数据集mtcars
周围显示同样的情况,定义middle
不会改变它。而且平均值与中位数之间存在较大差异。另一个选择是使用stat_summary
,尽管我无法使points函数正常工作,并且不得不对其进行调整以免出现arguments imply differing number of rows: 1, 0
错误。
BoxMeanQuant <- function(x) {
v <- c(min(x), quantile(x, 0.25), mean(x), quantile(x, 0.75), max(x))
names(v) <- c("ymin", "lower", "middle", "upper", "ymax")
v
}
mpg %>%
ggplot(aes(x = class, y = cty)) +
stat_summary(fun.data = BoxMeanQuant, geom = "boxplot")
与普通geom_boxplot
(未使用定义的middle
)相比。
mpg %>%
ggplot(aes(x = class, y = cty)) +
geom_boxplot(aes(middle = mean(cty)))
这就是我用来将离群值绘制为点的方法,但是它们与geom_boxplot
的默认值不同。您可以根据需要进行调整。不使用if-else
会引发错误。
BoxMeanQuant <- function(x) {
v <- c(quantile(x, 0.1), quantile(x, 0.25), mean(x), quantile(x, 0.75), quantile(x, 0.9))
names(v) <- c("ymin", "lower", "middle", "upper", "ymax")
v
}
outliers <- function(x) {
if (length(x) > 5) {
subset(x, x < quantile(x, 0.1) | quantile(x, 0.9) < x)
} else {
return(NA)
}
}
ggplot(data = mpg, aes(x = class, y = cty)) +
stat_summary(fun.data = BoxMeanQuant, geom = "boxplot") +
stat_summary(fun.y = outliers, geom = "point")
答案 1 :(得分:1)
最后,我必须创建一个摘要df来执行此操作。它不是我最初想要的,但是它可以工作。
df <- mpg %>%
group_by(class) %>%
summarize(ymin = min(cty), ymax = max(cty), lower = quantile(cty, 0.25), upper = quantile(cty, 0.75), middle = mean(cty))
df %>%
ggplot(aes(class)) +
geom_boxplot(aes(ymin = ymin, ymax = ymax, lower = lower, upper = upper, middle = middle), stat = 'identity')