使用R dplyr包分组处理缺失值:生成递增加3的WANT列
按ID分组生成递推WANT列的正确实现方法
先给个示例数据方便测试:
library(tibble) library(dplyr) library(purrr) df <- tibble( ID = c(1,1,1,2,2,2), X1 = c(10, NA, NA, 20, NA, NA) )
你之前用lead()函数不对是因为lead()是取下一行的值,而这里需要的是基于前一行计算结果的递推逻辑,完全不是一个路数。直接用purrr::accumulate()就能搞定,按ID分组后逐行计算:
df %>% group_by(ID) %>% mutate(WANT = accumulate(X1, ~ifelse(is.na(.y), .x + 3, .y))) %>% ungroup()
运行后结果如下:
# A tibble: 6 × 3 ID X1 WANT <dbl> <dbl> <dbl> 1 1 10 10 2 1 NA 13 3 1 NA 16 4 2 20 20 5 2 NA 23 6 2 NA 26
逻辑解释
accumulate()会按顺序遍历X1的每个元素:
- 第一个元素非NA,直接取
X1的值作为初始WANT - 后续元素如果是NA,就用前一个
WANT的值加3;如果非NA,直接替换成当前X1的值 - 按
ID分组后,每个组的递推都是独立的,不会跨组干扰
如果不想用purrr,也可以用基础dplyr函数实现:
df %>% group_by(ID) %>% mutate( # 先提取每个组的非NA起始值,填充NA的位置 base = fill(X1, .direction = "downup") %>% pull(X1), # 计算每个位置相对于起始值的偏移量:每个NA对应+3,非NA偏移0 offset = cumsum(ifelse(is.na(X1), 3, 0)), WANT = base + offset ) %>% select(-base, -offset) %>% ungroup()
这个方法是先把每个组的X1向下填充得到基准值,再计算每个位置的偏移量,最后相加得到结果,同样能达到需求。
内容的提问来源于stack exchange,提问作者bvowe
相关产品推荐
相关产品推荐

