Суммирование сгруппированных записей в кадре данных

У меня есть кадр данных в R, который выглядит так:

> TimeOffset, Source, Length 
> 0         1           1500
> 0.1       1           1000    
> 0.2       1           50
> 0.4       2           25
> 0.6       2           3
> 1.1       1           1500
> 1.4       1           18
> 1.6       2           2500
> 1.9       2           18
> 2.1       1           37
> ...

и я хочу преобразовать его в

> TimeOffset, Source, Length
> 0.2         1       2550
> 0.6         2       28
> 1.4         1       1518
> 1.9         2       2518
> ...

Пытаясь перевести это на английский язык, я хочу сгруппировать последовательные записи с одним и тем же «Источником» вместе, а затем распечатать одну запись для каждой группы, показывающую наибольшее смещение времени в этой группе, источник и сумму длин в этой группе. .

Значения TimeOffset всегда будут увеличиваться.

Я подозреваю, что это возможно в R, но я действительно не знаю, с чего начать. В крайнем случае я мог бы экспортировать фрейм данных и сделать это, например. Python, но я бы предпочел остаться в R, если это возможно.

Заранее благодарим за любую помощь, которую вы можете предоставить


person monch1962    schedule 15.04.2010    source источник


Ответы (2)


Сначала вам нужно создать переменную id, которая определяет ваши группы, не полагаясь на то, что они последовательны. После этого все довольно просто.

> dat <- data.frame(    TimeOffset = c(0,.1,.2,.4,.6,1.1,1.4,1.6,1.9,2.1),
+ Source=c(1,1,1,2,2,1,1,2,2,1),
+ Length=c(1500,1000,50,25,3,1500,18,2500,18,37))
> dat
   TimeOffset Source Length
1         0.0      1   1500
2         0.1      1   1000
3         0.2      1     50
4         0.4      2     25
5         0.6      2      3
6         1.1      1   1500
7         1.4      1     18
8         1.6      2   2500
9         1.9      2     18
10        2.1      1     37
> 
> id <- cumsum(c(TRUE,diff(dat$Source)!=0))
> id
 [1] 1 1 1 2 2 3 3 4 4 5
> 
> cbind(TimeOffset=tapply(dat$TimeOffset,id,max),
+ Source=tapply(dat$Source,id,max),
+ Length=tapply(dat$Length,id,sum))
  TimeOffset Source Length
1        0.2      1   2550
2        0.6      2     28
3        1.4      1   1518
4        1.9      2   2518
5        2.1      1     37
person Ian Fellows    schedule 15.04.2010

Я только что видел, и мне нравится решение Яна. Моя слишком сложная...

df <- read.table(textConnection("
TimeOffset Source Length 
 0         1           1500
 0.1       1           1000    
 0.2       1           50
 0.4       2           25
 0.6       2           3
 1.1       1           1500
 1.4       1           18
 1.6       2           2500
 1.9       2           18
 2.1       1           37
"),header=T)


ind <- cbind(rle(df$Source)[[1]],cumsum(rle(df$Source)[[1]]))
ind2 <- apply(ind,1,function(x) c(x[2]-(x[1]-1),x[2]))
ldply(apply(ind2,2,function(x) data.frame(df[x[2],1:2], Length=sum(df[x[1]:x[2],3]) ) ))

  TimeOffset Source Length
1        0.2      1   2550
2        0.6      2     28
3        1.4      1   1518
4        1.9      2   2518
5        2.1      1     37
person George Dontas    schedule 15.04.2010