编辑2:我意识到我可以使用dcast()
来做我想做的事情。但是,我不想计算事件数据中的所有事件,只计算在另一个数据集中指定的日期之前发生的事件。我似乎无法弄清楚如何在dcast()
中使用子集参数。到目前为止,我已经尝试过:
dcast(dt.events, Email ~ EventType, fun.aggregate = length, subset = as.Date(Date) <=
as.Date(dt.users$CreatedDate[dt.users$Email = dt.events$Email]))
然而,这不起作用。我可以将CreatedDate
中的dt.users
列添加到dt.events
。然后使用以下子集:
dcast(dt.events, Email ~ EventType, fun.aggregate = length, subset = as.Date(Date) <=
as.Date(CreatedDate)
我想知道是否可以在不添加额外列的情况下执行此操作?
编辑:刚刚计算出它可能需要大约37个小时才能完成我目前正在进行的工作,所以如果有人有任何提示可以让它更快。请让我知道:))
我是R的新手,我已经找到了一种方法来做我想做的事情。但效率极低,需要数小时才能完成。
我有以下内容:
活动数据:
UserID Email EventType Date
User1 User1@*.com Type2 2016-01-02
User1 User1@*.com Type6 2016-01-02
User1 User1@*.com Type1 2016-01-02
User1 User1@*.com Type3 2016-01-02
User2 User2@*.com Type1 2016-01-02
User2 User2@*.com Type1 2016-01-02
User2 User2@*.com Type2 2016-01-02
User3 User3@*.com Type1 2016-01-02
User3 User3@*.com Type3 2016-01-02
User1 User1@*.com Type2 2016-01-04
User1 User1@*.com Type2 2016-01-04
User2 User2@*.com Type5 2016-01-04
User3 User3@*.com Type1 2016-01-04
User3 User3@*.com Type4 2016-01-04
每次用户执行某项操作时,都会使用带有时间戳的事件类型记录事件。
来自不同数据库的用户列表:
UserID Email CreatedDate
DxUs1 User1@*.com 2016-01-01
DxUs2 User2@*.com 2016-01-03
DxUs3 User3@*.com 2016-01-03
我想获得以下内容:
汇总列表,用于计算用户列表中每个用户的事件数据中每种事件类型的数量。但是,只有在&#34; CreatedDate&#34;在用户列表中等于&#34;日期&#34;在事件数据中。
因此,对于上述数据,我最终希望得到:
Email Type1 Type2 Type3 Type4 Type5 Type6
User1@*.com 1 3 1 0 0 1
User2@*.com 0 0 1 0 1 0
User3@*.com 1 0 0 1 0 0
到目前为止我是如何设法的
我已经能够通过首先创建一个&#39; dt.master&#39; data.table,包括所有事件的所有列和电子邮件列表。看起来像这样:
Email Type1 Type2 Type3 Type4 Type5 Type6
User1@*.com 0 0 0 0 0 0
User2@*.com 0 0 0 0 0 0
User3@*.com 0 0 0 0 0 0
然后使用下面的while循环填写此表:
# The data sets
dt.events # event data
dt.users # user list
dt.master # blank master table
# Loop that fills master table
counter_limit = group_size(dt.master)
index = 1
while (index <= counter_limit) {
# Get events of user at current index
dt.events.temp = filter(dt.events, dt.events$Email %in% dt.users$Email[index],
as.Date(dt.events$Date) <= as.Date(dt.users$CreatedDate[index]))
# Count all the different events
dt.event.counter = as.data.table(t(as.data.table(table(dt.events.temp$EventType))))
# Clean the counter by 1: Rename columns to event names, 2: Remove event names row
names(dt.event.counter) = as.character(unlist(dt.event.counter[1,]))
dt.event.counter = dt.event.counter[-1]
# Fill the current index in on the blank master table
set(dt.master, index, names(dt.event.counter), dt.event.counter)
index = index + 1
}
问题
这确实有效......但我正在处理超过900万个事件,250k +用户,150多个事件类型。因此,上面的while循环在处理之前需要HOURS。我用一小批500个用户测试了它,它有以下处理时间:
user system elapsed
179.33 62.92 242.60
我还在等待整批处理哈哈。我已经读过应该避免循环的地方,因为它们需要花费很多时间。但是我对R和编程一般来说都是全新的,而且我一直在通过试用/错误和Google搜索来学习我需要的东西。显然,这会导致一些混乱的代码。我想知道是否有人能指出我可能更快/更有效的方向?
谢谢!
编辑:刚刚计算出它可能需要大约37个小时才能完成我目前正在进行的工作,所以如果有人有任何提示可以让它更快。请让我知道:))
TL,DR:我的事件聚合/汇总代码需要几个小时才能处理我的数据(它还没有完成)。有没有更快的方法呢?
答案 0 :(得分:3)
假设您的数据已经在data.table
,您可以使用fun.aggregate
中的dcast
参数:
dcast(dat, Email ~ EventType, fun.aggregate = length)
给出:
Email Type1 Type2 Type3 Type4 Type5 Type6
1: User1@*.com 1 2 1 0 0 1
2: User2@*.com 4 1 0 0 1 0
3: User3@*.com 0 1 1 1 0 0
回应评论&amp;更新的问题:您可以通过在dcast
- 函数中使用非等联接来获得所需的结果:
dcast(dt.events[dt.users, on = .(Email, Date >= CreatedDate)],
Email ~ EventType, fun.aggregate = length)
给出:
Email Type1 Type2 Type3 Type4 Type5 Type6
1: User1@*.com 1 2 1 0 0 1
2: User2@*.com 1 0 0 0 1 0
3: User3@*.com 0 1 0 1 0 0
答案 1 :(得分:2)
未测试
library(dpylr)
library(tidyr)
your.dataset %>%
count(Email, EventType) %>%
spread(EventType, n)