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

在R语言长格式数据集中创建随时间动态变化的哑变量

实现长格式数据集中的"ever urban"哑变量

核心需求

按个体分组,当个体首次出现urban=1后,后续所有记录的ever_urban均为1(即使后续urban变回0或NA);首次出现urban=1前的记录,若原urban为0则ever_urban=0,若原urban为NA则保留NA。


示例数据集

先构造符合场景的测试数据:

library(dplyr)

df <- tibble(
  id = rep(1:2, each = 5),
  time = 1:5,
  urban = c(0, 1, 0, NA, 0, 0, 0, NA, 1, 0)
)

解决方案1:使用dplyr(推荐,逻辑清晰)

利用cumany()判断个体是否曾出现过urban=1,结合case_when()处理NA和0的情况:

df_processed <- df %>%
  group_by(id) %>%
  mutate(
    ever_urban = case_when(
      # 只要曾出现过urban=1(忽略NA),后续所有行设为1
      cumany(urban == 1, na.rm = TRUE) ~ 1L,
      # 未出现过urban=1时,原urban为NA则保留NA
      is.na(urban) ~ NA_integer_,
      # 其余情况设为0
      TRUE ~ 0L
    )
  ) %>%
  ungroup()

处理后结果:

idtimeurbanever_urban
1100
1211
1301
14NA1
1501
2100
2200
23NANA
2411
2501

解决方案2:使用Base R(无需加载包)

用ave()按个体分组,结合cummax()和ifelse()处理:

df$ever_urban <- with(df, ave(urban, id, FUN = function(x) {
  # 先将NA替换为0,计算累积最大值(判断是否曾出现过1)
  cum_has_urban <- cummax(replace(x, is.na(x), 0))
  # 未出现过1时,原NA位置恢复为NA;其余情况用累积最大值
  ifelse(is.na(x) & cum_has_urban == 0, NA_integer_, cum_has_urban)
}))

常见问题排查

  1. 之前用cummax/cumsum得到1和NA的原因:

    • 未按个体分组,导致所有个体的urban值被混在一起计算;
    • 未处理NA,cummax()遇到NA会直接传递,覆盖前面的0值。
  2. NA保留逻辑:

    • 首次出现urban=1前的NA:保留NA(因为无法确定该记录是否为城市状态);
    • 首次出现urban=1后的NA:设为1(因为个体已经有过城市记录)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:03:22