[英]Connect medians within nested groups in ggplot?
我正在尝试 plot 这些不同的组,并用一条线连接每个组内每个系列(A、B、C)的中位数。
n <- 60
data <- data.frame(series=rep(LETTERS[1:3], n/3),
sex=rep(c("F","M"),each=30),
setting=rep(c("wild","rural"),n/2),
fit=rnorm(n))
ggplot(data,aes(x=sex, y=fit, fill=series)) +
geom_boxplot(width=.3,aes( alpha=.5,color=sex),
lwd=0.8, position = position_dodge(width = 0.6)) +
facet_grid(~setting) +
stat_summary(fun.y=median, geom="point", shape=23, size=2,
position=position_dodge(width = 0.6)) +
geom_text(aes(y=-2.5, label=series), position=position_dodge(width=0.6)) +
geom_point(shape=20,alpha=0.2,position=position_jitterdodge(dodge.width = 0.6,jitter.width = 0.25))+
theme_blank()
我一直在玩弄 geom_line 和 stats_summary,但不是很成功,因为分组似乎总是错误的。 这是我尝试使用 stats_summary 的示例,看起来像我真正想要的 4 条线(在每组中将 A 连接到 C),但由于某种原因没有被箱线图覆盖......
stat_summary(fun.y=median, colour="red", geom="line",aes(x=series, group=interaction(setting,sex)),
position=position_dodge(width = 0.6))
我在这里也找到了一个非常相似的已回答问题,但我无法让这个解决方案为我工作。 我在运行第二部分时收到一条错误消息( geom_line()
中的错误:计算美学时出现问题。ℹ 错误发生在第 4 层。由FUN()
中的错误引起:!object 未找到“系列”)
在这一点上,我也很乐意接受任何类型的解决方法,但我自己想不出。 谢谢!
基本上,这是对您引用的案例答案中的方法的改编,它使用“手动躲避”,这意味着计算x
(当然还有y
)。 手动定位中线。 为此,我们首先必须将映射到x
上的sex
列转换为数字。 其次,我们必须根据series
移动位置(当然要考虑到您躲避箱形图和点的width
),即对于 A 组,我们将 position 向左移动,对于组 C 向右移动。
set.seed(123)
library(ggplot2)
library(dplyr)
data_line <- data %>%
group_by(setting, sex, series) %>%
summarise(fit = median(fit)) |>
ungroup() |>
# Manual dodging
mutate(x_num = as.numeric(factor(sex)) + seq(-1, 1, length.out = 3) * .6 / 3)
#> `summarise()` has grouped output by 'setting', 'sex'. You can override using
#> the `.groups` argument.
ggplot(data, aes(x = sex, y = fit, fill = series)) +
geom_boxplot(
width = .3, aes(alpha = .5, color = sex),
lwd = 0.8, position = position_dodge(width = 0.6)
) +
facet_grid(~setting) +
stat_summary(
fun = median, geom = "point", shape = 23, size = 2,
position = position_dodge(width = 0.6)
) +
geom_line(data = data_line,
aes(x = x_num, group = sex),
colour = "red"
)+
geom_text(aes(y = -2.5, label = series), position = position_dodge(width = 0.6)) +
geom_point(shape = 20, alpha = 0.2, position = position_jitterdodge(dodge.width = 0.6, jitter.width = 0.25))
#> Warning: `position_dodge()` requires non-overlapping x intervals
#> `position_dodge()` requires non-overlapping x intervals
这与 Stefan 的方法类似,但计算是在 ggplot 中即时完成的:
library(ggplot2)
n <- 60
data <- data.frame(series=rep(LETTERS[1:3], n/3),
sex=rep(c("F","M"),each=30),
setting=rep(c("wild","rural"),n/2),
fit=rnorm(n))
ggplot(data, aes(x = as.numeric(interaction(series, sex)) +
1.5 * ((as.numeric(interaction(series, sex)) - 1) %/% 3),
y = fit, fill = series)) +
geom_boxplot(width = 0.5, aes(color = sex), alpha = 0.5) +
geom_point(fun = median, stat = "summary", shape = 23, size = 2) +
geom_text(aes(y = -2.5, label = series)) +
geom_point(shape = 20, alpha = 0.2, position = position_jitter(0.25)) +
geom_line(stat = "summary", fun = median, aes(group = sex)) +
facet_grid(~setting) +
scale_x_continuous(NULL, breaks = c(2, 6.5), labels = c("F", "M"),
limits = c(0, 8.5)) +
ggnetwork::theme_blank() +
theme(axis.text.x.bottom = element_text(), strip.background = element_blank())
创建于 2022-12-14,使用reprex v2.0.2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.