我有一组非常大的数据来自id和日期。该数据集有几亿行,大约有1000万个id。我在非Windows环境中运行,具有足够的RAM和多个处理器。我正在做这件事。目前,我正在使用multidplyr,但我正在考虑所有选项。
例如:
> df[1:11,]
id date gap episode
1 100000019 2015-01-24 0 1
2 100000019 2015-02-20 27 1
3 100000019 2015-03-31 39 2
4 100000019 2015-04-29 29 2
5 100000019 2015-05-27 28 2
6 100000019 2015-06-24 28 2
7 100000019 2015-07-24 30 2
8 100000019 2015-08-23 30 2
9 100000019 2015-09-21 29 2
10 100000019 2015-10-22 31 3
11 100000019 2015-12-30 69 4
数据在函数调用之前排序。订单很重要。对于每个ID,在第一个日期之后,我需要确定每个后续日期之间的天数。我称之为差距。因此,id的第一个日期得到零差距。第二个日期获取第二个日期的值减去前一行中的日期。等等。
我按ID分割数据,然后将每个id的数据发送到以下函数。
assign_gap <- function(x) {
# x$gap <- NA
for(i in 1:nrow(x)) {
x[i, ]$gap <- ifelse(i == 1, 0, x[i,]$date - x[i-1, ]$date)
}
return(x)
}
cluster <- create_cluster(8)
cluster_assign_value(cluster, 'assign_gap', assign_gap)
system.time(df <- df %>% partition(id, cluster = cluster) %>% do(assign_gap(.)) %>% collect())
然后我应用另一个函数,它根据allowable_gap将日期间隙的顺序分组为“剧集”(我使用的值为30)。因此,每个id可能会根据日期顺序和间隙分配多个剧集。
assign_episode <- function(x, allowable_gap){
ep <- 1
for(i in 1:nrow(x)){
ifelse(x[i,]$gap <= allowable_gap, ep <- ep, ep <- ep + 1)
x[i, ]$episode <- ep
}
return(x)
}
cluster <- create_cluster(8)
cluster_assign_value(cluster, 'assign_episode', assign_episode)
cluster_assign_value(cluster, 'allowable_gap', allowable_gap)
system.time(df <- df %>% partition(id, cluster = cluster) %>% do(assign_episode(., allowable_gap)) %>% collect())
鉴于我拥有的数据量,我真的想找到一种方法来避免函数中的这些循环,我希望这会大大提高效率。如果有人能想到一个完成同样事情的替代方案,我将不胜感激。
答案 0 :(得分:1)
我建议使用data.table
库。这个库非常快,特别是如果你正在使用像你这样的大型数据集。这是一个部分解决方案,我解决了问题的第一步:
gap
,确保每个id
的第一行为0 library(data.table)
setDT(df)
df[, gap := c(0L, diff(date)) , by = id ]
即使这不是并行工作,我希望这段代码比你目前使用的循环更快。
episode
位于gap
下30
id
我还没有找到问题第二部分的解决方案,但如果他们找到解决方案,我会鼓励其他人补充这个答案。