R 在数据帧中汇总分组记录

R 在数据帧中汇总分组记录,r,select,dataframe,R,Select,Dataframe,我在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

我在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
> ...
试着把它转换成英语,我想把具有相同“源”的连续记录分组在一起,然后每组打印出一条记录,显示该组中的最高时间偏移、源以及该组中的长度总和

时间偏移值将始终增加

我怀疑这在R中是可能的,但我真的不知道从哪里开始。在紧要关头,我可以导出数据帧并用Python来完成,但如果可能的话,我更愿意留在R中


提前感谢您提供的任何帮助

首先,您需要创建一个
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
>dat-dat
时间偏移源长度
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
> 
>身份证
[1] 1 1 1 2 2 3 3 4 4 5
> 
>cbind(TimeOffset=tapply(dat$TimeOffset,id,max),
+Source=tapply(数据$Source,id,最大值),
+长度=塔普利(dat$长度、id、总和))
时间偏移源长度
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

我刚看到,我喜欢伊恩的解决方案。我的太复杂了

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
df
# 'dfx' refers to the 'input' data frame in OP's Question
# use run-length encoding to get contiguous rows having the same Source value
a = rle(dfx$Source)
row_groups = a$lengths

result = matrix(rep(0,3))   
attr(result, "dim") = c(1,3)

fnx = function(a_df){
  c1 = max(a_df[,1])
  c2 = a_df[1,2]
  c3 = sum(a_df[,3])
  cbind(c1, c2, c3)
}


for (itm in row_groups){
  px = dfx[1:itm,]
  dfx = dfx[-(1:dim(px)[1]),]
  result = rbind(result, fnx(px))
}

result = result[-1,]
# returns:  
     c1  c2  c3
[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