基于dplyr/tidyverse筛选数据:保留2岁参赛次数超3次的马匹并绘制箱线图的实现方法
解决方法:筛选2岁参赛超3次的马匹并绘制箱线图
我来帮你搞定这个问题!你的思路方向是对的,但关键是要先锁定符合条件的马匹名单,而不是只筛选它们2岁的记录——毕竟你要的是这些马的所有年龄数据来做箱线图对吧?
两种优雅的实现方式:
方式1:先获取合格马匹名单,再过滤数据
这种方式逻辑清晰,适合新手理解:
library(tidyverse) # 1. 先找出2岁时参赛次数超过3次的马匹 qualified_horses <- df %>% filter(age == 2) %>% # 只看2岁的记录 count(horse) %>% # 统计每匹马2岁的参赛次数 filter(n > 3) %>% # 筛选参赛次数>3的马 pull(horse) # 提取马匹名称作为向量 # 2. 过滤原数据,只保留这些马的所有年龄记录 filtered_df <- df %>% filter(horse %in% qualified_horses) # 3. 绘制箱线图(修复了fun.y弃用的警告) filtered_df %>% ggplot(aes(x=as.factor(age), y=value, fill=as.factor(age))) + geom_boxplot(alpha=0.7) + stat_summary(fun=mean, geom="point", shape=20, size=8, color="red", fill="red") + stat_summary(fun = mean, geom = "text", col = "black", vjust = -1.5, aes(label = paste("X:", round(..y.., digits = 1)))) + theme(legend.position="none") + scale_fill_brewer(palette="Set1")
方式2:一步到位的管道写法(更简洁)
如果想少些中间变量,用管道直接完成筛选和绘图:
df %>% group_by(horse) %>% # 给每匹马添加一列,记录它2岁时的参赛次数 mutate(race_count_2yo = sum(age == 2)) %>% ungroup() %>% # 只保留2岁参赛次数>3的马匹数据 filter(race_count_2yo > 3) %>% # 直接绘图 ggplot(aes(x=as.factor(age), y=value, fill=as.factor(age))) + geom_boxplot(alpha=0.7) + stat_summary(fun=mean, geom="point", shape=20, size=8, color="red", fill="red") + stat_summary(fun = mean, geom = "text", col = "black", vjust = -1.5, aes(label = paste("X:", round(..y.., digits = 1)))) + theme(legend.position="none") + scale_fill_brewer(palette="Set1")
为什么你的原方法有问题?
你之前尝试group_by(horse, age)然后summarise,这样会把每个马的每个年龄都分开统计,最后筛选的只是2岁参赛次数不够的行,而不是整个马匹。我们需要的是把这些马的所有数据都保留/排除,所以必须先锁定马匹名单,再过滤整个数据集。
内容的提问来源于stack exchange,提问作者Mutuelinvestor
相关产品推荐
相关产品推荐

