R语言:如何创建记录最近0出现间隔的计算列
R语言:基于最近一次0的位置生成新列
原始数据
d <- data.frame(Item = c(1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0))
需求说明
需要给数据框d新增一列recent,规则如下:
- 若当前行
Item值为0,则recent值为0; - 若当前行
Item值为1,则recent值为距离最近的上一个0的行数间隔(比如最近的0在上一行,值为1;上两行则为2,依此类推); - 第一行因无前置0,
recent值为NA。
预期结果
最终新增列的目标值为:
c(NA, 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 1, 0, 1, 2, 3, 0)
解决方案
方法1:Base R 原生实现
通过分组计数的思路,先标记0的位置生成分组,再对每组内的行计算间隔:
# 生成分组标识:每遇到一个0就开启新分组 d$group <- cumsum(d$Item == 0) # 对每个分组计算行索引差,匹配规则生成目标列 d$recent <- ave(seq(nrow(d)), d$group, FUN = function(x) { if (x[1] == 1) { # 第一行(无前置0)返回NA NA } else { # 分组内行号减去该组第一个0的行号,得到间隔值 x - x[1] } }) # 清理临时分组列 d$group <- NULL
方法2:dplyr 管道风格实现
如果习惯使用tidyverse工具链,可通过分组和条件判断实现:
library(dplyr) d <- d %>% mutate( # 标记每个0起始的分组 group = cumsum(Item == 0), # 按规则生成目标列 recent = case_when( row_number() == 1 ~ NA_integer_, Item == 0 ~ 0L, TRUE ~ row_number() - min(row_number()[group == cur_group()]) ) ) %>% select(-group)
运行上述任意一种方法后,数据框d将包含符合要求的recent列。
内容的提问来源于stack exchange,提问作者Benjamin Colbert
相关产品推荐
相关产品推荐

