(我今天早些时候尝试过问这个问题,但后来才意识到我过度简化了问题;我收到的答案是正确的,但由于我在原问题中对问题的过度简化,我无法使用它们这是我的第二次尝试......)
我在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&该组的持续时间(= EndTime-StartTime),以及该组的长度总和,以及该组中内容(将全部为字符串)的串联。
TimeOffset值将始终在整个数据框中增加。
我看了一下熔化/重铸并且感觉它可以用来解决问题,但无法理解文档。我怀疑在R中可以做到这一点,但我真的不知道从哪里开始。在紧要关头,我可以将数据帧导出并在例如Python,但如果可能的话,我宁愿呆在R里面。
提前感谢您提供的任何帮助
答案 0 :(得分: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 = ", ")
)
答案 1 :(得分: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)
P.S。:您需要将结果转换为“正确”格式,因为最终结果是字符串矩阵。
答案 2 :(得分: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