考虑data.table
包含id1
,id2
之间多年匹配的 id1 year id2
1: 51557094 2003 65122111
2: 51557094 2004 65122111
3: 51557094 2005 65122111
4: 51557094 2007 65122111
5: 51557094 2008 65122111
6: 51557093 2006 65122111
。
id1 year id2 length
1: 51557094 2003 65122111 3
2: 51557094 2007 65122111 2
3: 51557093 2006 65122111 1
对于任何这些比赛,我想找出比赛的持续时间以及比赛开始的年份。如果特定年份没有数据,则匹配结束(如果再次有数据,则下一年将开始新匹配。)
因此,对于上面的样本数据,预期输出将是
> dtId
id1 year id2
1: 51557094 2003 65122111
2: 51557094 2004 65122111
3: 51557094 2005 65122111
4: 51557094 2007 65122111
5: 51557094 2008 65122111
6: 51557094 2006 65122112
> setkey(dtId, id1, id2, year)
> dtId[,grp := cumsum(c(1,diff(year)) > 1),by=id1]
> dtId[,list(year=year[1],length=length(year)),by=list(id1,id2,grp)]
id1 id2 grp year length
1: 51557094 65122111 0 2003 5
2: 51557094 65122112 0 2006 1
我接受了其中一个答案,因为它给我带来了足够的意义,但注意到它不正确。虽然它适用于样本数据,但不适用于以下
grp
相反,在id1, id2
上创建匹配变量> dtId[,grp := cumsum(c(1,diff(year)) > 1),by=list(id1, id2)]
> dtId[,list(year=year[1],length=length(year)),by=list(id1,id2,grp)]
id1 id2 grp year length
1: 51557094 65122111 0 2003 3
2: 51557094 65122112 0 2006 1
3: 51557094 65122111 1 2007 2
可以解决问题:
{{1}}
答案 0 :(得分:3)
尝试:
dat[,grp := cumsum(c(1,diff(year)) > 1),by=list(id1,id2)]
dat[,list(year=year[1],length=length(year)),by=list(id1,id2,grp)]
# id1 id2 grp year length
#1: 51557094 65122111 0 2003 3
#2: 51557094 65122111 1 2007 2
#3: 51557093 65122111 0 2006 1
答案 1 :(得分:1)
首先,让我们构建你的表
library(data.table)
dtId <- data.table(
id1 = c(rep(51557094, 5), 51557093),
year = c(2000 + c(3, 4, 5, 7, 8, 6)),
id2 = rep(65122111, 6)
)
我们可以对它进行排序并添加一个&#34; newMatch&#34;如果新匹配开始,则为TRUE的列,即与上一行相比,年份没有增加1。
dtId <- dtId[order(id1, id2, year)]
dtId[, newMatch := c(FALSE, year[-1] != year[-.N] + 1)]
现在我们可以添加&#34;匹配&#34;列是哪个值是匹配ID,我们可以聚合。
dtId[, match := cumsum(newMatch)]
dtAggr <- dtId[
, list(year = min(year), length = .N),
by = c("id1", "id2", "match")
]
删除&#34;匹配&#34;我们有预期的结果。
dtAggr[, match := NULL]
dtAggr