R 按两列排序并保持联系

R 按两列排序并保持联系,r,data.table,dplyr,rank,R,Data.table,Dplyr,Rank,我的问题是这个问题的继续 我有这样一个数据集: ID | Date A 01/01/2015 A 02/01/2015 A 02/01/2015 A 02/01/2015 A 05/01/2015 B 01/01/2015 我想根据参考日期(2015年1月31日)对每个日期进行排名。与参考日期最近的日期排名为1,第二位为2,依此类推。结果如下: ID

我的问题是这个问题的继续

我有这样一个数据集:

 ID    |     Date 

  A        01/01/2015
  A        02/01/2015
  A        02/01/2015
  A        02/01/2015
  A        05/01/2015     
  B        01/01/2015
我想根据参考日期(2015年1月31日)对每个日期进行排名。与参考日期最近的日期排名为1,第二位为2,依此类推。结果如下:

  ID    |     Date           |  Sequence

  A        01/01/2015           3
  A        02/01/2015           2
  A        02/01/2015           2
  A        02/01/2015           2
  A        05/01/2015           1  
  B        01/01/2015          ...
虽然排名函数确实在思考,但我也希望保持所有的联系。我该怎么做


此外,我正在处理一个巨大的数据集—大约3亿行。因此,理想的解决方案应该是快速的

这里有一个
data.table
方法可以工作

rleid
按组ID返回同一日期的“ID”。但是,这些ID从0开始计数。在第二个链中,
[
(max(var)-var)+1L
为每个ID组反转这些日期ID

df[, var:=rleid(Date), by=ID][, var := (max(var) - var) + 1L, by=ID]
df
   ID       Date var
1:  A 01/01/2015   3
2:  A 02/01/2015   2
3:  A 02/01/2015   2
4:  A 02/01/2015   2
5:  A 05/01/2015   1
6:  B 01/01/2015   1

我们可以使用
frank
from
data.table
density
as
ties.method
通过
abs上的“ID”进行分组后,得出“日期”和参考日期(“2015-01-31”)之间的绝对差异

数据
df带有
dplyr
密集等级

library(dplyr)
df$Sequence <- dense_rank(as.numeric(as.Date('31/01/2015', '%d/%m/%Y') - as.Date(df$Date, '%d/%m/%Y')))
head(df) 

  ID       Date Sequence
1  A 01/01/2015        3
2  A 02/01/2015        2
3  A 02/01/2015        2
4  A 02/01/2015        2
5  A 05/01/2015        1
6  B 01/01/2015        3
库(dplyr)

df$SequenceBase
R
解决方案。首先通过将天数和目标日期转换为
date
对象并获取差值的绝对值来获取它们

timediff <- abs(as.Date(df[["Date"]], format = "%d/%m/%Y") - as.Date("2015-01-31"))
最后,我们可以使用它对列组进行重新排序,以消除实例之间的间隙

df[["Sequence"]] <- as.numeric(factor(diffrank))

df[[“Sequence”]]谢谢你的回复。我在想这样的事情:var:=(max(var)-var)+1L,by=ID,但我不知道如何实现它。谢谢。效果很好。我实际上并不知道frank函数。只是一个快速的跟进。我们可以这样做吗:setDT(df)[,Sequence:=frank(Date,ties.method=“random”),by=ID]以加快处理速度?它可以完美地处理较小的对象。但对于较大的对象,它不会移动任何人。仅供参考,frank+ties.method=“dense”在dplyr中具有类似的稠密级别。我可能会在较小的数据集上尝试它。但我认为它会比data.table解决方案慢一些。
timediff <- abs(as.Date(df[["Date"]], format = "%d/%m/%Y") - as.Date("2015-01-31"))
diffrank <- rank(timediff, ties.method = "min")
df[["Sequence"]] <- as.numeric(factor(diffrank))
df[["Sequence"]] <- as.numeric(factor(rank(
                        abs(as.Date(df[["Date"]], format = "%d/%m/%Y") - 
                               as.Date("2015-01-31")), ties.method = "min")))