Суммирование сгруппированных записей в кадре данных в R (... снова) - PullRequest
2 голосов
/ 15 апреля 2010

(Я пытался задать этот вопрос ранее сегодня, но позже понял, что я слишком упростил вопрос; полученные ответы были правильными, но я не мог их использовать из-за чрезмерного упрощения задачи в исходном вопросе Вот моя вторая попытка ...)

У меня есть кадр данных в 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 всегда будут увеличиваться во всем фрейме данных.

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

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

Ответы [ 3 ]

7 голосов
/ 15 апреля 2010

Вот еще одно решение с использованием 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 голосов
/ 15 апреля 2010

Придерживаюсь моего (не элегантного) пути

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
2 голосов
/ 15 апреля 2010

Попробуйте это:

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 .: Вам необходимо преобразовать результат в «правильный» формат, поскольку конечный результат представляет собой матрицу строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...