我的问题是此探测的继续Link
我有一个这样的数据集:
JSONArray items = new JSONArray(jsonStr );
我想按照参考日期对每个日期进行排名 - 2015年1月31日。与参考日期最接近的日期排名为1,排名第二,依此类推。结果如下:
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
虽然排名功能确实存在,但我也希望保持所有联系。我怎么做?
另外,我正在处理一个庞大的数据集 - 约。 3亿行。所以解决方案理想情况下会很快。
答案 0 :(得分:2)
我们可以使用frank
的{{1}} data.table
dense
作为ties.method
,然后按ID' ID'关于日期'日期'之间的abs
olute差异和参考日期(' 2015-01-31')
library(data.table)
setDT(df)[, Sequence := frank(abs(as.IDate(Date, "%d/%m/%Y")-
as.IDate("2015-01-31")), ties.method = "dense"), by = ID]
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 1
df <- structure(list(ID = c("A", "A", "A", "A", "A", "B"), Date = c("01/01/2015",
"02/01/2015", "02/01/2015", "02/01/2015", "05/01/2015", "01/01/2015"
)), .Names = c("ID", "Date"), class = "data.frame", row.names = c(NA,
-6L))
答案 1 :(得分:2)
使用dplyr
dense_rank
:
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
答案 2 :(得分:1)
这是一个可行的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
答案 3 :(得分:1)
基础R
解决方案。首先通过将它们转换为Date
个对象并获取差异的绝对值来获取您的日期和目标日期。
timediff <- abs(as.Date(df[["Date"]], format = "%d/%m/%Y") - as.Date("2015-01-31"))
接下来,我们可以使用rank
来获取它们的顺序。我们可以使用为关系生成单个值的任何ties.method
,但"min"
或"max"
可能是最好的,因为它们输出整数。
diffrank <- rank(timediff, ties.method = "min")
最后,我们可以使用this solution重新排序排名,以消除实例之间的差距。
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")))