我在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里面。
提前感谢您提供的任何帮助
答案 0 :(得分:6)
首先,您需要创建一个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
答案 1 :(得分:2)
我刚刚看到,我喜欢伊恩的解决方案。我太复杂了......
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
答案 2 :(得分:0)
# '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