Редактирование 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 [email protected]*.com Type2 2016-01-02
User1 [email protected]*.com Type6 2016-01-02
User1 [email protected]*.com Type1 2016-01-02
User1 [email protected]*.com Type3 2016-01-02
User2 [email protected]*.com Type1 2016-01-02
User2 [email protected]*.com Type1 2016-01-02
User2 [email protected]*.com Type2 2016-01-02
User3 [email protected]*.com Type1 2016-01-02
User3 [email protected]*.com Type3 2016-01-02
User1 [email protected]*.com Type2 2016-01-04
User1 [email protected]*.com Type2 2016-01-04
User2 [email protected]*.com Type5 2016-01-04
User3 [email protected]*.com Type1 2016-01-04
User3 [email protected]*.com Type4 2016-01-04
Каждый раз, когда пользователь делает что-то, событие записываются с типом события, с отметкой времени.
список пользователей из различных баз данных:
UserID Email CreatedDate
DxUs1 [email protected]*.com 2016-01-01
DxUs2 [email protected]*.com 2016-01-03
DxUs3 [email protected]*.com 2016-01-03
Я хочу, чтобы получить следующее:
, сокращенного список, который подсчитывает количество каждого типа события в данных событиях для каждого пользователя в Список пользователей. Однако события должны учитываться только в том случае, если «Созданная дата» в списке пользователей до или равна «Дате» в данных события.
Таким образом, для приведенных выше данных, я бы в конечном итоге хотите получить:
Email Type1 Type2 Type3 Type4 Type5 Type6
[email protected]*.com 1 3 1 0 0 1
[email protected]*.com 0 0 1 0 1 0
[email protected]*.com 1 0 0 1 0 0
Как мне удалось сделать это до сих пор
Я был в состоянии сделать это сначала создать таблицу данных dt.master, включающую все столбцы для всех событий и список писем. Который выглядит следующим образом:
Email Type1 Type2 Type3 Type4 Type5 Type6
[email protected]*.com 0 0 0 0 0 0
[email protected]*.com 0 0 0 0 0 0
[email protected]*.com 0 0 0 0 0 0
А затем заполнить эту таблицу, используя время цикла ниже:
# 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
}
Проблема
Это работает ... Тем не менее, я имею дело с 9+ миллионов событий, 250k + пользователей, 150+ типов событий. Поэтому вышеописанный цикл принимает HOURS до его обработки.Я проверил это с небольшой партией 500 пользователей, которые имели следующее время обработки:
user system elapsed
179.33 62.92 242.60
Я все еще в ожидании полной партии, чтобы быть обработаны ха-ха. Я где-то читал, что следует избегать циклов, поскольку они занимают много времени. Однако я совершенно новичок в R и программировании в целом, и я изучаю пробную версию/ошибку и Googling независимо от того, что мне нужно. Очевидно, что это приводит к некорректному коду. Мне было интересно, может ли кто-нибудь указать мне в сторону чего-то, что может быть быстрее/эффективнее?
Спасибо!
Редактировать: Просто рассчитано, что, вероятно, потребуется около 37 часов, чтобы завершить то, как я это делаю сейчас, поэтому, если у кого есть какие-либо советы, чтобы сделать это быстрее. Пожалуйста, дайте мне знать :)
TL, DR: Мое сообщение об агрегировании/суммировании событий занимает несколько часов, чтобы обработать мои данные (это еще не сделано). Есть ли более быстрый способ сделать это?
вы должны проверить длинный/широкий format - '? reshape()' – BigDataScientist
Я откат назад, поскольку решения принадлежат к ответам, надеюсь, что вы не против – Jaap
Кроме того: поздравляю с первым вопросом на SO! Хорошо сформулированный и, следовательно, пример для всех новых пользователей imo. – Jaap