根据日期和 R 中的排名回顾列

Look back column based on date and rank in R

我正在尝试创建一个基于排名的新列,每个月都会更改。以下是示例输入数据。

df <- data.frame(id=c(1,1,1,1,1,1,1,2,2,2,3,3,4),
             rank=c(3,1,1,1,1,1,2,2,3,1,1,2,3),
             dates=c('2019-06-15','2019-07-15','2019-08-15','2019-09-15','2019-10-15','2019-11-15','2019-12-15',
                     '2019-10-15','2019-11-15','2019-12-15',
                     '2019-11-15','2019-12-15','2019-12-15'))

这是预期的输出,我想要最新日期的行。

 id   rank   dates      new_col
  1    2    2019-12-15       0
  2    1    2019-12-15       0
  3    2    2019-12-15       1
  4    3    2019-12-15       0

new_col 将表明 rank 从 6 个月的回顾中有所增加? 例如,如果某行来自 12 月 2 但它们在 10 月的行中为 1,则 在 December 行中,我们可以输入 new_col= 1.

我们必须将回顾日期限制在 6 个月

假设您愿意使用data.table。首先在时间变量之后对数据进行排序。使用 shift 获取最后 2 个可用值(在您的情况下为 6),并取最大值。需要确保每个 ID 都有完整的时间序列,否则,我认为它将采用最后可用的值。通过将排名与 rank_max 进行比较,您可以确定排名是否发生变化。

library(data.table)
df <- data.table(id=c(1,1,1,2,2,2,3,3,3) %>% as.character,
             rank=c(1,3,2,2,3,1,1,2,3),
             time=rep(1:3,3))
setorder(df, time)
df[, rank_max := do.call(pmax, shift(rank, 1:2, type = "lag")), by=id]

   id rank time rank_max
1:  1    1    1       NA
2:  2    2    1       NA
3:  3    1    1       NA
4:  1    3    2       NA
5:  2    3    2       NA
6:  3    2    2       NA
7:  1    2    3        3
8:  2    1    3        3
9:  3    3    3        2

这是在 data.table 中使用非等值连接的选项:

#convert into IDate and get dates from 6m ago
DT[, dates := as.IDate(dates, format="%Y-%m-%d")][, c("start", "end") := 
    .(as.IDate(sapply(dates, function(x) seq(x, by="-6 months", length.out=2L)[2L])), dates)]

#extract latest rows for each id
latest <- DT[DT[, .I[.N], id]$V1]

#non-equi join and for each latest date of each id, check if the current rank is the highest over last 6m
DT[latest, on=.(id, dates>=start, dates<end), 
    by=.EACHI, {
        a <- +all(i.rank > x.rank)
        .(new_col=replace(a, is.na(a), 0L))
        }]

输出:

   id      dates      dates new_col
1:  1 2019-06-15 2019-12-15       0
2:  2 2019-06-15 2019-12-15       0
3:  3 2019-06-15 2019-12-15       1
4:  4 2019-06-15 2019-12-15       0

数据:

library(data.table)
DT <- data.table(id=c(1,1,1,1,1,1,1,2,2,2,3,3,4),
    rank=c(3,1,1,1,1,1,2,2,3,1,1,2,3),
    dates=c('2019-06-15','2019-07-15','2019-08-15','2019-09-15','2019-10-15','2019-11-15','2019-12-15',
        '2019-10-15','2019-11-15','2019-12-15',
        '2019-11-15','2019-12-15','2019-12-15'))