2014-12-03 5 views
1

Рассмотрите 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 

ответ

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

Я принял ваш ответ, но учтите, что вы можете его исправить (см. Обновленный вопрос). – FooBar

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) 
) 

Мы можем сортировать его и добавить столбец «newMatch», который является ИСТИННЫМ, если начинается новое совпадение, то есть год не увеличился на один по сравнению с предыдущей строкой.

dtId <- dtId[order(id1, id2, year)] 
dtId[, newMatch := c(FALSE, year[-1] != year[-.N] + 1)] 

Теперь мы можем добавить столбец «match», значение которого является идентификатором соответствия, и мы можем агрегировать.

dtId[, match := cumsum(newMatch)] 
dtAggr <- dtId[ 
    , list(year = min(year), length = .N), 
    by = c("id1", "id2", "match") 
    ] 

Извлечение столбца «match» имеет ожидаемый результат.

dtAggr[, match := NULL] 
dtAggr 
Смежные вопросы