如何在R语言DataFrame中提取分组后首次出现非零值的记录?
提取动物首次产仔时间的R实现
问题描述
我们需要从包含id、rep、age、babies字段的DataFrame中,按id和rep分组,仅保留每组中首次出现babies非零的行,以此获取动物首次产仔的年龄。
原始数据如下:
id <- c("A","A","A","A","A","A","B","B","B","B","B","B","B","B","B") rep <- c(1,1,1,2,2,2,1,1,1,1,2,2,2,2,2) age <- c(0,1,2,0,1,2,0,1,2,3,0,1,2,3,4) babies <- c(0,0,1,0,1,0,0,0,0,1,0,0,0,1,1) df <- data.frame(id,rep,age,babies)
期望输出结果:
id <- c("A","A","B","B") rep <- c(1,2,1,2) age <- c(2,1,3,3) babies <- c(1,1,1,1) df <- data.frame(id,rep,age,babies)
解决方案
方法1:使用dplyr包(tidyverse风格)
先安装并加载dplyr包,通过分组、筛选非零值、取每组第一行实现需求:
library(dplyr) result <- df %>% group_by(id, rep) %>% filter(babies != 0) %>% slice(1) %>% ungroup() print(result)
方法2:使用Base R(无需额外包)
利用ave函数计算每组内非零值的累积计数,筛选出计数为1的非零行:
result <- df[ave(df$babies != 0, df$id, df$rep, FUN = cumsum) == 1 & df$babies != 0, ] print(result)
两种方法均可得到目标结果:dplyr写法直观易读,适合复杂数据处理场景;Base R方法无需依赖第三方包,适合轻量需求。
内容的提问来源于stack exchange,提问作者Rspacer
相关产品推荐
相关产品推荐

