【发布时间】:2015-04-10 04:07:43
【问题描述】:
我的数据看起来像这样:
foo <- data.frame(userid = c("a","a","b","b","b"),
activity = factor(c("x","y","z","z","x")),
st=c(0, 20, 0, 10, 25), # start time
et=c(20, 30, 10, 25, 30)) # end time
对于每个用户 ID,我希望将活动数据转换为五分钟的时间段。结果看起来像这样:
result <- data.frame(userid = c("a", "b"),
x1 = c("x", "z"),
x2 = c("x", "z"),
x3 = c("x", "z"),
x4 = c("x", "z"),
x5 = c("y", "z"),
x6 = c("y", "x"))
下面的方法有效,但是相当麻烦而且速度很慢。在我的中等大小的数据集上,这大约需要 15 分钟。
library(dplyr)
library(tidyr)
lvls <- levels(foo$activity)
time_bin <- function(st, et, act) {
bins <- seq(0, 30, by=5)
tb <- as.integer(bins>=st & bins<et)*as.integer(act)
tb[tb>0] <- lvls[tb]
data.frame(tb=tb, bins=bins)
}
new_foo <-
foo %>%
rowwise() %>%
do(data.frame(., time_bin(.$st, .$et, .$activity))) %>%
select(-(activity:et)) %>%
group_by(userid) %>%
subset(tb>0) %>%
spread(bins, tb)
有没有更快或更方便的方法来解决这个问题?
【问题讨论】:
-
我们能否在输入中假设每个用户的活动是 a) 不重叠 b) 两者之间没有间隙 c) 按增加的时间排序?也许您可以提供更长的(随机种子生成的)输入来对性能进行压力测试?您的意思是说您的代码仅在五行输入上就花费了 15 分钟?
标签: r performance dplyr binning