如何在R语言分组内统计连续出现次数并忽略NA值
问题
需要按country和person分组,在忽略缺失值(NA)的前提下统计ocurrences变量的连续出现次数,规则如下:
- 当
ocurrences为0时,count设为0并重置计数 - 当
ocurrences为NA时,count为NA - 连续出现1时,
count依次递增
现有数据集定义:
df <- data.frame(country = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B","B"), person = c("a", "a", "a", "b", "b", "a", "a", "b", "b", "b","b"), time = c(1,2,3,1,2,1,2,1,2,3,4), ocurrences = c(1,1,NA,1,0,0,NA,1,1,0,1))
数据集展示:
country person time ocurrences 1 A a 1 1 2 A a 2 1 3 A a 3 NA 4 A b 1 1 5 A b 2 0 6 B a 1 0 7 B a 2 NA 8 B b 1 1 9 B b 2 1 10 B b 3 0 11 B b 4 1
期望输出:
country person time ocurrences count 1 A a 1 1 1 2 A a 2 1 2 3 A a 3 NA NA 4 A b 1 1 1 5 A b 2 0 0 6 B a 1 0 0 7 B a 2 NA NA 8 B b 1 1 1 9 B b 2 1 2 10 B b 3 0 0 11 B b 4 1 1
解决方案
可以使用dplyr包实现分组计数逻辑,具体代码如下:
library(dplyr) df_result <- df %>% group_by(country, person) %>% mutate( # 生成子组标记:遇到0、NA或分组首行时,标记为新子组起点 group_id = cumsum(is.na(ocurrences) | ocurrences == 0 | row_number() == 1), # 按规则生成count列 count = case_when( is.na(ocurrences) ~ NA_integer_, ocurrences == 0 ~ 0L, TRUE ~ row_number() - match(group_id, unique(group_id)) + 1L ) ) %>% select(-group_id) %>% # 移除临时辅助变量 ungroup() print(df_result)
代码逻辑说明
- 一级分组:按
country和person分组,保证每个个体的计数独立进行。 - 子组划分:通过
cumsum生成group_id,把连续的1划分为独立子组,遇到0、NA或分组首行时开启新子组。 - count列生成:
- 若
ocurrences为NA,直接返回NA; - 若
ocurrences为0,返回0并重置后续计数; - 连续1的情况,在对应子组内按行号递增计数。
- 若
- 清理输出:移除临时变量
group_id,取消分组后得到最终结果。
内容的提问来源于stack exchange,提问作者Victor Shin
相关产品推荐
相关产品推荐

