使用dplyr统计每个Id分组末尾连续NA值的简便方法
基于dplyr统计分组末尾连续NA数量的实现方法
需求说明
按Id字段分组,仅当分组最后一个value值为NA时,统计末尾连续出现的NA数量,否则返回0。
示例数据
library(dplyr) library(lubridate) my_data <- tibble(Id =c(1,1,1,2,2,2),date = rep(seq.Date(ymd(20210101),ymd(20210103),by =1 ),2), value = c(5, NA, 4, 4, NA, NA))
预期输出
# A tibble: 2 × 2 Id Result <dbl> <dbl> 1 1 0 2 2 2
原有代码问题
你编写的代码使用了filter逻辑,会直接剔除最后一个值不为NA的分组(也就是示例中的Id=1),导致最终结果缺失对应行的0值。
推荐实现方法
方法1:rle逻辑判断实现(可读性高)
在summarise内直接做条件判断,无需提前过滤分组:
my_data %>% group_by(Id) %>% arrange(date, .by_group = TRUE) %>% # 确保分组内按日期升序排列,避免数据顺序混乱影响结果 summarise(Result = { na_vec <- is.na(value) # 分组最后一个值不为NA直接返回0 if (!last(na_vec)) return(0) # 否则取rle结果最后一段的长度,即为末尾连续NA数量 tail(rle(na_vec)$lengths, 1) })
方法2:向量运算实现(代码更简洁)
利用cumprod的特性直接计算,无需额外条件判断:
my_data %>% group_by(Id) %>% arrange(date, .by_group = TRUE) %>% summarise(Result = sum(is.na(value) * rev(cumprod(rev(is.na(value))))))
两种方法都可以得到符合预期的输出结果。
内容的提问来源于stack exchange,提问作者Felipe
相关产品推荐
相关产品推荐

