原文链接:http://www.tbk.ren/article/254.html?source=csdn
有的同学在处理自己的业务逻辑的时候,需要用到Row Number的方法,那么,什么是Row Number呢?
例如我们有下面的数据,第一列是用户的ID,第二列是用户的购买日期,现在如果我们需要判断用户是否重复购买,并且,每一次的购买,下一次的购买时间间隔是多少呢?
id,date
1,20150601
1,20150603
2,20150601
2,20150605
2,20150610
3,20150503
3,20150603
4,20150601
如果我们可以处理称为下面的数据,那么这个问题就完美解决了:
id date.x datey
0 1 20150601 20150603.0
1 1 20150603 NaN
2 2 20150601 20150605.0
3 2 20150605 20150610.0
4 2 20150610 NaN
5 3 20150503 20150603.0
6 3 20150603 NaN
7 4 20150601 NaN
date_y就是下一次的购买时间,date_y-date_x就是前后两次的购买间隔。
> install.packages(
+ "data.table",
+ repos= c("http://R-Forge.R-project.org", getOption("repos"))
+ )
>
> library(data.table)
>
> data <- read.csv("data.csv")
>
> data <- data.table(data)
#使用data.table的新增列的方法,注意下面的写法,rank是函数,-date是指根据date的相反值进行排序,by是我们要分组的字段。
> data[, valRank:=rank(-date), by="id"]
>
> data
id date valRank
1: 1 20150601 2
2: 1 20150603 1
3: 2 20150601 3
4: 2 20150605 2
5: 2 20150610 1
6: 3 20150503 2
7: 3 20150603 1
8: 4 20150601 1
>
在这里,我们可以看到,所谓的row Number,就是指在指定的分组中,它相对于非分组列,也就是date的排序号,这种方法,又叫做partition rank的方法,其实都是指这么回事。
因为,我们希望得到某行对下一行的连接,因此,下一行,减一,就可以和上一行对应上了。
> data[, valRank_1:=valRank-1]
>
这样子,我们就可以得到以下的结果了,我们通过筛选列,就可以得到我们的目标数据了。
> merge(data, data, all.x = TRUE, by.x = c("id", "valRank"), by.y = c("id", "valRank_1"))
id valRank date.x valRank_1 date.y valRank
1: 1 1 20150603 0 20150601 2
2: 1 2 20150601 1 NA NA
3: 2 1 20150610 0 20150605 2
4: 2 2 20150605 1 20150601 3
5: 2 3 20150601 2 NA NA
6: 3 1 20150603 0 20150503 2
7: 3 2 20150503 1 NA NA
8: 4 1 20150601 0 NA NA
>