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

如何使用lag函数为R数据框添加最近NoShow日期列?

需求:为分组用户添加最近一次未赴约日期列

我有一个包含Person、NoShow和date列的DataFrame:

Person NoShow       date
1     123      0 2019-01-01
2     123      1 2019-04-01
3     123      0 2020-01-01
4     123      1 2021-01-01
5     123      0 2021-04-30
6     123      0 2022-01-05
7     334      0 2019-07-07
8     334      1 2019-10-11
9     334      1 2020-07-07
10    334      0 2021-01-04

创建该DataFrame的代码:

df <- data.frame(Person = c('123','123','123','123','123','123','334','334','334','334'), 
                   NoShow = c(0,1,0,1,0,0,0,1,1,0), 
                   date = c('2019-01-01','2019-04-01','2020-01-01','2021-01-01','2021-04-30','2022-01-05','2019-07-07','2019-10-11','2020-07-07','2021-01-04')
                   )

我已经通过lag函数创建了两个新列:

  • prior_noshow:标识用户是否有过之前未赴约的记录
  • prior_noshow_f:统计用户之前未赴约的次数

创建这两个列的代码:

library(tidyverse)

df %>% 
  group_by(Person) %>%
  mutate(prior_noshow = lag(as.numeric(cumsum(NoShow) > 0)),
         prior_noshow_f = lag(cumsum(NoShow)))

添加后的DataFrame如下:

Person NoShow date       prior_noshow prior_noshow_f
   <chr>   <dbl> <chr>             <dbl>          <dbl>
 1 123         0 2019-01-01           NA             NA
 2 123         1 2019-04-01            0              0
 3 123         0 2020-01-01            1              1
 4 123         1 2021-01-01            1              1
 5 123         0 2021-04-30            1              2
 6 123         0 2022-01-05            1              2
 7 334         0 2019-07-07           NA             NA
 8 334         1 2019-10-11            0              0
 9 334         1 2020-07-07            1              1
10 334         0 2021-01-04            1              2

现在需要添加prior_noshow_date列,显示每位用户最近一次未赴约的日期。例如:

  • 第3、4行的prior_noshow_date应为2019-04-01
  • 第5、6行应为2021-01-01

解决方案

可以通过标记未赴约日期、向下填充最近日期再偏移的方式实现,代码如下:

library(tidyverse)

df %>% 
  group_by(Person) %>%
  mutate(
    # 标记未赴约的日期,非未赴约行设为NA
    noshow_date = ifelse(NoShow == 1, date, NA),
    # 向下填充最近的未赴约日期,再用lag偏移一行得到"之前"的记录
    prior_noshow_date = lag(fill(noshow_date, .direction = "down"))
  ) %>%
  # 保留之前的两个统计列
  mutate(
    prior_noshow = lag(as.numeric(cumsum(NoShow) > 0)),
    prior_noshow_f = lag(cumsum(NoShow))
  ) %>%
  select(-noshow_date) # 移除中间辅助列

运行后得到的结果:

Person NoShow date       prior_noshow_date prior_noshow prior_noshow_f
   <chr>   <dbl> <chr>      <chr>                      <dbl>          <dbl>
 1 123         0 2019-01-01 NA                             NA             NA
 2 123         1 2019-04-01 NA                              0              0
 3 123         0 2020-01-01 2019-04-01                      1              1
 4 123         1 2021-01-01 2019-04-01                      1              1
 5 123         0 2021-04-30 2021-01-01                      1              2
 6 123         0 2022-01-05 2021-01-01                      1              2
 7 334         0 2019-07-07 NA                             NA             NA
 8 334         1 2019-10-11 NA                              0              0
 9 334         1 2020-07-07 2019-10-11                      1              1
10 334         0 2021-01-04 2020-07-07                      1              2

逻辑说明

  1. 标记未赴约日期:用ifelse筛选出NoShow=1的行,保留对应日期,其余行设为NA;
  2. 填充最近日期:fill(..., .direction = "down")会把每个未赴约日期向下填充,直到遇到下一个未赴约日期,确保后续行能拿到最近的未赴约记录;
  3. 偏移得到"之前"的记录:lag函数将填充后的日期整体向后偏移一行,让每一行对应到当前记录发生前的最近未赴约日期;
  4. 最后移除中间辅助列,保持DataFrame结构整洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:54:20