我有一个大数据框(600万行),其中一行用于输入时间,另一行用于相同单位(id)的退出时间。我需要把它们放在一起。
原始数据类似于以下内容(请注意,某些“id”可能会像id = 1一样进入和退出两次):
df <- read.table(header=T, text='id time
1 "15/12/2014 06:30"
1 "15/12/2014 06:31"
1 "15/12/2014 06:34"
1 "15/12/2014 06:35"
2 "15/12/2014 06:36"
2 "15/12/2014 06:37"
3 "15/12/2014 06:38"
3 "15/12/2014 06:39"')
我需要的输出:
id entry exit
1 15/12/2014 06:30 15/12/2014 06:31
2 15/12/2014 06:34 15/12/2014 06:35
3 15/12/2014 06:36 15/12/2014 06:37
4 15/12/2014 06:38 15/12/2014 06:39
现在我尝试了一个for循环,它从第1行中选择id和入口时间,从第2行中选择退出时间,并将它们组合在一起:
for (i in 1:nrow(df)){
outputdf[i,1] <- df[i+i-1,1]
outputdf[i,2] <- df[i+i-1,2]
outputdf[i,3] <- df[i+i-1+1,2]
}
问题在于效率非常低(适用于10k子集,但不适用于我的600万数据帧)。我需要的东西至少需要不到一分钟。我在df
中有600万行。你知道比这个循环更快的任何替代方案来匹配行吗?
答案 0 :(得分:1)
你可以尝试
library(data.table)
dcast.data.table(setDT(df)[ ,c('.id', 'Seq'):=
list(c('entry', 'exit'), gl(.N,2, .N))], id+Seq~.id, value.var='time')
# id Seq entry exit
#1: 1 1 15/12/2014 06:30 15/12/2014 06:31
#2: 1 2 15/12/2014 06:34 15/12/2014 06:35
#3: 2 3 15/12/2014 06:36 15/12/2014 06:37
#4: 3 4 15/12/2014 06:38 15/12/2014 06:39
df <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L), time =
structure(1:8, .Label = c("15/12/2014 06:30",
"15/12/2014 06:31", "15/12/2014 06:34", "15/12/2014 06:35", "15/12/2014 06:36",
"15/12/2014 06:37", "15/12/2014 06:38", "15/12/2014 06:39"), class
= "factor")),.Names = c("id", "time"), class = "data.frame", row.names
= c(NA, -8L))
答案 1 :(得分:1)
也许我错过了什么,但是这个怎么样?
indx <- seq(1,nrow(df)-1,2)
result <- with(df,data.frame(seq=seq(indx),id=id[indx],entry=time[indx],exit=time[indx+1]))
result
# seq id entry exit
# 1 1 1 15/12/2014 06:30 15/12/2014 06:31
# 2 2 1 15/12/2014 06:34 15/12/2014 06:35
# 3 3 2 15/12/2014 06:36 15/12/2014 06:37
# 4 4 3 15/12/2014 06:38 15/12/2014 06:39