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

问题描述 投票:0回答:2

我正在尝试根据排名创建一个新列,每个月都在变化。以下是样本输入数据。

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是否表示从6个月的回顾起rank会增加?例如,如果从12月起的一行是2,但在10月的一行中是1,则在十二月行中,我们可以将new_col = 1。

我们必须将回溯日期限制为6个月

r dplyr data.table plyr
2个回答
0
投票

假设您愿意使用data.table。首先在时间变量之后对数据进行排序。使用shift获取最后2个可用值(在您的情况下为6个),并取最大值。我认为,需要确保每个ID都有完整的时间序列,否则,它将采用最后可用的值。通过比较rank和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

0
投票

这里是在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'))
© www.soinside.com 2019 - 2024. All rights reserved.