2010-04-15 45 views
2

(我今天早些时候试过问这个问题,但后来意识到我过分简化了问题;我收到的答案是正确的,但我无法使用他们是因为在原来的问题的问题我过于简单化这是我第2次尝试...)在R中的数据框中总结分组记录(...再次)

我有一个数据帧R中,看起来像:

"Timestamp", "Source", "Target", "Length", "Content" 
0.1  , P1  , P2  , 5  , "ABCDE" 
0.2  , P1  , P2  , 3  , "HIJ" 
0.4  , P1  , P2  , 4  , "PQRS" 
0.5  , P2  , P1  , 2  , "ZY" 
0.9  , P2  , P1  , 4  , "SRQP" 
1.1  , P1  , P2  , 1  , "B" 
1.6  , P1  , P2  , 3  , "DEF" 
2.0  , P2  , P1  , 3  , "IJK" 
... 

,我想转换这对:

"StartTime", "EndTime", "Duration", "Source", "Target", "Length", "Content" 
0.1  , 0.4  , 0.3  , P1  , P2  , 12  , "ABCDEHIJPQRS" 
0.5  , 0.9  , 0.4  , P2  , P1  , 6  , "ZYSRQP" 
1.1  , 1.6  , 0.5  , P1  , P2  , 4  , "BDEF" 
... 

试图把这个写成英文,我想将同一个'源'和'目标'连续记录在一起,然后打印出每个组的单个记录,显示StartTime,EndTime & Duration(= EndTime-StartTime)组以及该组的长度总和,以及该组中的内容(其全部是字符串)的串联。

在整个数据帧中,TimeOffset值将始终增加。

我看过融化/重铸,并有一种感觉,它可以用来解决问题,但不能让我的头在文档。我怀疑在R内部可以这样做,但我真的不知道从哪里开始。在掐我可以导出数据帧,并在例如Python,但如果可能的话,我宁愿留在R中。

预先感谢任何帮助,您可以提供

回答

7

下面是使用plyr另一种解决方案:

id <- with(df1, paste(Source, Target)) 
df1$group <- cumsum(c(TRUE, id[-1] != id[-length(id)])) 

library(plyr) 
ddply(df1, c("group"), summarise, 
    start = min(Timestamp), 
    end = max(Timestamp), 
    content = paste(Content, collapse = ", ") 
) 
+0

喜欢这个解决方案 - 简单,优雅和完美的作品。谢谢哈德利! – monch1962 2010-04-16 00:37:17

2

试试这个:

id <- as.numeric(gsub("P","",paste(df$Source,df$Target,sep=""))) 
df$id <- cumsum(c(TRUE,diff(id)!=0)) 
res <- by(df, df$id, 
      function(x) { 
      len <- nrow(x) 
      start <- x[1,1] 
      end <- x[len,1] 
      dur <- end - start 
      src <- x[1,2] 
      trg <- x[1,3] 
      len <- sum(x[,4]) 
      cont <- paste(x[,5],collapse="") 
      return(c(start,end,dur,src,trg,len,cont)) 
      } 
     ) 
do.call(rbind,res) 

PS:您需要将结果转换为“正确”的格式,最后的结果是一个矩阵的字符串。

2

坚持我的(不优雅)的方式

df1 <- read.table(textConnection(" 
Timestamp Source Target Length Content 
0.1   P1  P2  5  ABCDE 
0.2   P1  P2  3  HIJ 
0.4   P1  P2  4  PQRS 
0.5   P2  P1  2  ZY 
0.9   P2  P1  4  SRQP 
1.1   P1  P2  1  B 
1.6   P1  P2  3  DEF 
2.0   P2  P1  3  IJK 
"),header=T) 

df <- adply(df1, 1 ,transform, newSource = 
as.numeric(paste(substr(Source, 2, 2),substr(Target, 2, 2),sep="")) ) 

ind <- cbind(rle(df$newSource)[[1]],cumsum(rle(df$newSource)[[1]])) 
ind2 <- apply(ind,1,function(x) c(x[2]-(x[1]-1),x[2])) 
res <- ldply(apply(ind2,2,function(x) data.frame(StartTime = df[x[1],1] , 
EndTime = df[x[2],1] , 
Duration = df[x[2],1] - df[x[1],1] , 
Source = df[x[1],2] , 
Target = df[x[1],3] , 
Length=sum(df[x[1]:x[2],4]) , 
Content=paste(df[x[1]:x[2],5],collapse="") 
))) 

    StartTime EndTime Duration Source Target Length  Content 
1  0.1  0.4  0.3  P1  P2  12 ABCDEHIJPQRS 
2  0.5  0.9  0.4  P2  P1  6  ZYSRQP 
3  1.1  1.6  0.5  P1  P2  4   BDEF 
4  2.0  2.0  0.0  P2  P1  3   IJK