R语言多约束筛选dataframe:保留唯一id且取最小visit对应行
R dataframe按ID分组保留最小visit行的实现方法
需求说明
需要对dataframe dat 完成子集筛选,满足两个约束:
- 保留每个唯一
id对应的记录 - 同一个
id仅保留visit字段取值最小的行
示例数据
运行以下代码生成测试数据集:
set.seed(42) ## 保证结果可复现 n <- 6 dat <- data.frame(id=c("s1","s2","s2","s3","s4","s4"), date=seq.Date(as.Date("2020-12-26"), as.Date("2020-12-31"), "day"), visit=1:2, age=sample(18:30, n, replace=TRUE))
原始数据结构:
| id | date | visit | age |
|---|---|---|---|
| s1 | 2020-12-26 | 1 | 18 |
| s2 | 2020-12-27 | 2 | 22 |
| s2 | 2020-12-28 | 1 | 18 |
| s3 | 2020-12-29 | 2 | 26 |
| s4 | 2020-12-30 | 1 | 27 |
| s4 | 2020-12-31 | 2 | 21 |
期望输出结构:
| id | date | visit | age |
|---|---|---|---|
| s1 | 2020-12-26 | 1 | 18 |
| s2 | 2020-12-28 | 1 | 18 |
| s3 | 2020-12-29 | 2 | 26 |
| s4 | 2020-12-30 | 1 | 27 |
实现方法
方法1:基础R实现(无需安装额外依赖包)
res <- dat[as.logical(ave(dat$visit, dat$id, FUN = function(x) x == min(x))), ]
方法2:dplyr实现(代码可读性高,适合日常分析场景)
library(dplyr) # 写法1:用filter筛选最小visit对应的行 res <- dat %>% group_by(id) %>% filter(visit == min(visit)) %>% ungroup() # 写法2:用slice_min直接提取最小行,语法更简洁 res <- dat %>% group_by(id) %>% slice_min(visit, n = 1) %>% ungroup()
方法3:data.table实现(运行速度快,适合百万行以上的大数据量场景)
library(data.table) setDT(dat) res <- dat[, .SD[visit == min(visit)], by = id]
内容的提问来源于stack exchange,提问作者frankieb
相关产品推荐
相关产品推荐

