如何在R中添加列统计最近二进制变量标记后的累计年份?
解决R数据框中计算距离最近flag的累计年份问题
问题分析
你需要生成year_since列,要求在flag=1的行值为0,后续行逐年累加,无前置flag的行设为NA。原代码仅处理了flag后的第一行,无法实现连续累加,且order_by参数使用错误。
解决方案
根据需求的不同(按行顺序计数/按实际年份差计数),提供两种实现方式:
方式一:按数据框行顺序计数(忽略年份间隔)
这种方式下,无论实际年份是否连续,每一行在flag后依次加1:
library(dplyr) df <- data.frame(year = c(2000,2001,2002,2003,2004, 2005,2006,2007,2008,2010), flag = c(0,0,0,1,0,0,0,1,0,0)) df <- df %>% # 生成分组标识:每次flag=1时分组号递增 mutate(group = cumsum(flag)) %>% group_by(group) %>% # 组内计算:找到flag=1的行位置,后续行按行号差计数 mutate(year_since = ifelse(group == 0, NA, row_number() - which(flag == 1))) %>% ungroup() %>% select(-group) # 移除临时分组列 print(df)
输出结果:
year flag year_since 1 2000 0 NA 2 2001 0 NA 3 2002 0 NA 4 2003 1 0 5 2004 0 1 6 2005 0 2 7 2006 0 3 8 2007 1 0 9 2008 0 1 10 2010 0 2
方式二:按实际年份差计数(考虑年份间隔)
如果需要计算当前年份与最近flag年份的实际差值(比如2010与2007的差为3),可以用填充最近flag年份的方式:
library(dplyr) library(tidyr) df <- data.frame(year = c(2000,2001,2002,2003,2004, 2005,2006,2007,2008,2010), flag = c(0,0,0,1,0,0,0,1,0,0)) df <- df %>% # 记录flag=1对应的年份,其余行设为NA mutate(last_flag_year = ifelse(flag == 1, year, NA)) %>% # 向下填充最近的flag年份 fill(last_flag_year, .direction = "down") %>% # 计算年份差,无前置flag的行设为NA mutate(year_since = ifelse(is.na(last_flag_year), NA, year - last_flag_year)) %>% select(-last_flag_year) # 移除临时列 print(df)
输出结果:
year flag year_since 1 2000 0 NA 2 2001 0 NA 3 2002 0 NA 4 2003 1 0 5 2004 0 1 6 2005 0 2 7 2006 0 3 8 2007 1 0 9 2008 0 1 10 2010 0 3
原代码问题说明
- 仅处理单一行:原代码通过
lag(flag, n=1)仅检查前一行是否为flag,只能为flag后的第一行赋值,后续行因year_since为NA,lag(year_since)也为NA,无法实现累加。 - order_by参数错误:
lag函数的order_by需要传入变量(如year),而非字符串"year"。
内容的提问来源于stack exchange,提问作者Matthias M
相关产品推荐
相关产品推荐

