如何在ggbetweenstats中自动生成首日期与后续日期的对比列表?
问题描述
我正在随时间测量一些物理指标,希望使用ggbetweenstats绘制小提琴图。想要让第一个日期组与所有后续日期组进行对比,无需为每张图、每一天手动编写并更新comparisons列表。
尝试的思路是选择所有唯一日期,创建一个两列的数据集(第一列为最早日期,第二列为其他所有日期)再转换为列表,但未达到预期效果,运行代码时报错。
可复现代码
library(nycflights13) CarrierList <- unique(flights$carrier) i=12 a <- flights %>% mutate(departureDay = lubridate::make_date(year, month, day)) %>% dplyr::filter(origin =="JFK" & carrier==CarrierList[i]& departureDay<="2013-01-10"& departureDay>="2013-01-02") %>% select(departureDay) %>% unique() %>% arrange(departureDay) %>% slice(1) aa <- flights %>% mutate(departureDay = lubridate::make_date(year, month, day)) %>% dplyr::filter(origin =="JFK" & carrier==CarrierList[i]& departureDay<="2013-01-10"& departureDay>="2013-01-02") %>% select(departureDay) %>% unique() %>% arrange(departureDay)%>% slice(2:n()) ggbetweenstats( data = flights %>% mutate(departureDay = lubridate::make_date(year, month, day)) %>% dplyr::filter(origin =="JFK" & carrier==CarrierList[i] & departureDay<="2013-01-10" & departureDay>="2013-01-02"), x=departureDay, y = arr_delay, pairwise.display = "none", p.adjust.method = "holm", type = "nonparametric", ggtheme = jtools::theme_apa()) + ggsignif::geom_signif(map_signif_level = c("***"=0.001, "**"=0.01, "*"=0.05), comparisons = list(data.frame(a$departureDay,aa$departureDay) ))
报错信息
`Computation failed in `stat_signif()` Caused by error in `mapped_discrete()`: ! Can't convert `x` <data.frame> to <double>.`
期望效果
希望实现手动编写comparisons列表的等价效果(即最早日期分别与后续每个日期对比),示例手动代码如下:
ggbetweenstats( data = flights %>% mutate(departureDay = lubridate::make_date(year, month, day)) %>% dplyr::filter(origin =="JFK" & carrier==CarrierList[i] & departureDay<="2013-01-10" & departureDay>="2013-01-02"), x=departureDay, y = arr_delay, pairwise.display = "none", p.adjust.method = "holm", type = "nonparametric", ggtheme = jtools::theme_apa()) + ggsignif::geom_signif(y_position = c(300, 310, 320, 330, 340, 350, 360, 370), map_signif_level = c("***"=0.001, "**"=0.01, "*"=0.05), comparisons = list(c("2013-01-02", "2013-01-03"), c("2013-01-02", "2013-01-04"), c("2013-01-02", "2013-01-05"), c("2013-01-02", "2013-01-06"), c("2013-01-02", "2013-01-07"), c("2013-01-02", "2013-01-08"), c("2013-01-02", "2013-01-09"), c("2013-01-02", "2013-01-10")) )
也曾尝试另一种方法,但无法保留日期格式:
b <- lapply( 1:7, function(i) c( combn(a$departureDay, 2)[2, i], combn(aa$departureDay, 2)[1, i] ) )
解决方案
错误原因
你传递给comparisons的是一个包含数据框的列表,但geom_signif要求的是由字符向量组成的列表,每个向量包含两个要对比的组名称(这里是日期的字符形式),直接传入数据框会导致类型转换错误。
正确生成comparisons列表的方法
可以先提取最早日期的字符形式,再将其与后续每个日期的字符形式配对,生成符合要求的列表:
library(nycflights13) library(tidyverse) library(ggstatsplot) library(ggsignif) library(jtools) library(lubridate) # 提前处理数据,避免重复计算 filtered_data <- flights %>% mutate(departureDay = make_date(year, month, day)) %>% filter(origin == "JFK", carrier == CarrierList[12], departureDay >= "2013-01-02", departureDay <= "2013-01-10") # 获取排序后的唯一日期向量(字符格式) unique_dates <- filtered_data %>% pull(departureDay) %>% unique() %>% sort() %>% as.character() # 生成comparisons列表:第一个日期与所有后续日期配对 comparison_list <- map(unique_dates[-1], ~ c(unique_dates[1], .x)) # 绘制图形 ggbetweenstats( data = filtered_data, x = departureDay, y = arr_delay, pairwise.display = "none", p.adjust.method = "holm", type = "nonparametric", ggtheme = theme_apa() ) + ggsignif::geom_signif( y_position = seq(300, 370, by = 10), map_signif_level = c("***"=0.001, "**"=0.01, "*"=0.05), comparisons = comparison_list )
关键步骤说明
- 提前过滤数据:避免重复执行相同的
mutate和filter操作,提升代码效率和可读性。 - 统一日期格式为字符:将日期转换为字符形式,确保
geom_signif能正确识别组名称。 - 用
map生成对比列表:利用purrr::map遍历除第一个日期外的所有日期,自动生成每个对比对,无需手动编写。
这样就能自动生成符合要求的comparisons列表,实现第一个日期与所有后续日期的对比,且代码可复用,无需手动更新。
内容的提问来源于stack exchange,提问作者Massimiliano Landini
相关产品推荐
相关产品推荐

