代码之家  ›  专栏  ›  技术社区  ›  monch1962

总结R中数据帧中的分组记录(…再次)

  •  2
  • monch1962  · 技术社区  · 16 年前

    (我今天早些时候试着问这个问题,但后来意识到我把问题简化了;我收到的答案是正确的,但是我不能使用它们,因为我对原始问题的问题过于简化了。这是我第二次尝试……)

    我在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"
    ...
    

    尝试将其转换为英语,我希望将具有相同“源”和“目标”的连续记录组合在一起,然后每组打印一条记录,显示该组的开始时间、结束时间和持续时间(=endtime starttime),以及该组的长度总和,以及内容的串联(全部为字符串)s)在该组中。

    时间偏移值在整个数据帧中始终会增加。

    我看了一下熔化/重铸,觉得可以用它来解决问题,但无法理解文档。我怀疑这是可能的,但我真的不知道从哪里开始。在紧急情况下,我可以导出数据帧,然后在python中执行,但如果可能的话,我更愿意留在r中。

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

    3 回复  |  直到 16 年前
        1
  •  7
  •   Collin    16 年前

    下面是另一个使用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 = ", ")
    )
    
        2
  •  2
  •   teucer    16 年前

    试试这个:

    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)
    

    P.S.:您需要将结果转换为“正确”格式,因为最终结果是字符串矩阵。

        3
  •  2
  •   Yorgos    16 年前

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

    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