You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为国家-年份维度自然灾害数据框创建自上次事件以来的年份计数变量(R语言一行高效实现)

一行代码实现years_since变量计算

当然有办法用一行(链式)代码高效搞定这个需求!我来给你分享一个基于dplyr的简洁实现,完全匹配你的要求:

library(dplyr)

test <- test %>%
  group_by(country) %>%
  mutate(years_since = replace(cumsum(ifelse(!is.na(incident), 0, 1)) * NA^(cumsum(!is.na(incident)) == 0), !is.na(incident), 0)) %>%
  ungroup()

代码逻辑拆解:

  • 先通过group_by(country)按国家分组,保证每个国家的计算独立进行
  • 核心计算部分分几步:
    1. ifelse(!is.na(incident), 0, 1):把有灾害的行标记为0,无灾害的标记为1
    2. cumsum(...):对标记值累加,这样每次遇到灾害行时累加值不会增加(加0),之后的行依次递增1
    3. NA^(cumsum(!is.na(incident)) == 0):生成一个“掩码”——首次灾害发生前的所有行,cumsum(!is.na(incident))结果为0,NA^0等于NA;灾害发生后的行则会乘以1,保留累加值
    4. 最后用replace(..., !is.na(incident), 0)把所有有灾害的行强制设为0,完美处理连续灾害的情况(比如bbb的1993和1994年)
  • ungroup()取消分组,恢复数据框的常规状态

运行结果验证

执行后你会得到完全符合预期的输出:

# A tibble: 18 × 4
    year country incident years_since
   <int> <chr>   <chr>          <dbl>
 1  1990 aaa     NA                NA
 2  1991 aaa     Drought            0
 3  1992 aaa     NA                 1
 4  1993 aaa     NA                 2
 5  1994 aaa     NA                 3
 6  1995 aaa     NA                 4
 7  1990 bbb     NA                NA
 8  1991 bbb     NA                NA
 9  1992 bbb     NA                NA
10  1993 bbb     Flood              0
11  1994 bbb     Flood              0
12  1995 bbb     NA                 1
13  1990 ccc     NA                NA
14  1991 ccc     NA                NA
15  1992 ccc     NA                NA
16  1993 ccc     NA                NA
17  1994 ccc     NA                NA
18  1995 ccc     NA                NA

如果不想依赖dplyr,也可以用基础R写一行(虽然可读性稍差):

test$years_since <- unlist(tapply(seq(nrow(test)), test$country, function(x) {
  inc_flag <- !is.na(test$incident[x])
  res <- cumsum(!inc_flag)
  res[!cumsum(inc_flag)] <- NA
  res[inc_flag] <- 0
  res
}))

不过显然dplyr的链式写法更简洁直观,也更贴合现代R数据分析的习惯。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:12:46