You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言dplyr如何按条件最大值筛选分组数据?

问题描述

我有按测试及各测试内部子组分组的数据,采集了一系列比例值,以及用于判断各比例值显著性的p值,数据的基本结构如下:

testid <- paste0("T", c(rep(1, 5), rep(2, 5)))
groupid <- rep(1:5, 2)
prop <- c(0.98, 0.76, 0.54, 0.32, 0.1, 0.79, 0.32, 0.09, 0.04, 0.01)
pval <- c(0.01, 0.02, 0.03, 0.04, 0.1, 0.03, 0.06, 0.25, 0.35, 0.45)

library(dplyr)
df <- tibble(testid, groupid, prop, pval)

df

# A tibble: 10 x 4
   testid groupid  prop  pval
   <chr>    <int> <dbl> <dbl>
 1 T1           1  0.98  0.01
 2 T1           2  0.76  0.02
 3 T1           3  0.54  0.03
 4 T1           4  0.32  0.04
 5 T1           5  0.1   0.1 
 6 T2           1  0.79  0.03
 7 T2           2  0.32  0.06
 8 T2           3  0.09  0.25
 9 T2           4  0.04  0.35
10 T2           5  0.01  0.45

需求是针对每个测试,提取p值小于0.05的所有子组中groupid数值最大的对应记录,预期输出结果如下:

desired <- df %>% 
  filter((testid == "T1" & groupid == 4) | (testid == "T2" & groupid == 1))

desired

# A tibble: 2 x 4
  testid groupid  prop  pval
  <chr>    <int> <dbl> <dbl>
1 T1           4  0.32  0.04
2 T2           1  0.79  0.03

之前编写的代码运行不符合预期,两个测试都仅返回了groupid为1的记录:

x <- df %>%
  group_by(testid) %>%
  filter(row_number() <= max(pval < 0.5)[1])

已确认每个测试至少存在一个p<0.05的子组,优先使用dplyr实现。

解决方案

原代码问题说明

  1. 阈值设置错误:代码中写的是pval < 0.5,和需求的pval < 0.05不符
  2. 逻辑错误:max(pval < 0.05)是对逻辑向量取最大值,只要组内存在符合p<0.05的记录就会返回TRUE,等价于数值1,因此row_number() <= 1只会返回每组的第一行记录,自然只能拿到groupid=1的结果。

正确实现代码

写法1:基础filter逻辑(兼容性最好)

result <- df %>%
  group_by(testid) %>%
  filter(pval < 0.05) %>% # 先筛选出当前测试下p值小于0.05的所有子组
  filter(groupid == max(groupid)) %>% # 保留上述子组中groupid最大的记录
  ungroup()

写法2:使用slice_max(dplyr 1.0.0及以上版本支持,更简洁)

result <- df %>%
  group_by(testid) %>%
  filter(pval < 0.05) %>%
  slice_max(order_by = groupid, n = 1) %>% # 直接按groupid降序取第一行
  ungroup()

两种写法运行后得到的结果和预期输出完全一致。

内容的提问来源于stack exchange,提问作者markyoung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:30:05