Это похоже на этот пост о задержке dplyr и это сообщение о задержке изменения dplyr, но ни один из них не задает этот вопрос о том, что по умолчанию входное значение. Я использую dplyr для изменения нового поля, которое представляет собой запаздывающее смещение другого поля (которое я преобразовал в POSIXct). Цель состоит в том, что для данного IP-адреса я хотел бы получить некоторую сводную статистику по разнице между моментами, когда он появляется в моем списке. У меня тоже около 12 миллионов строк.
Данные выглядят так (до мутации)
ip hour snap
192.168.1.2 2017070700 0
192.168.1.2 2017070700 15
192.168.1.4 2017070700 0
192.168.1.4 2017070701 45
192.168.1.4 2017070702 30
192.168.1.7 2017070700 15
«час» - целое число, но должно быть отметкой времени.
«моментальный снимок» - это одно из 4 значений «моментального снимка», которые соответствуют 15-минутному приращению.
Вот код создания data.frame:
test <- data.frame(ip=c("192.168.1.2","192.168.1.2","192.168.1.4","192.168.1.4","192.168.1.4","192.168.1.7"), hour=c(2017070700,2017070700,2017070700,2017070701,2017070702,2017070700), snap=c(0,15,0,45,30,15))
На каждый IP-адрес приходится сотни, а иногда и тысячи временных меток. В приведенном ниже коде используется dplyr для
- а) дополнить 0 ведущим 0,
- б) объединить два целочисленных поля "дата" в одно поле,
- c) преобразовать объединенное целочисленное поле 'date' в дату POSIX,
- г) группировать по ip,
- e) изменить новый столбец, который отстает от старой метки времени на 1, и, если значение равно NA, вернуться к исходному значению (ЭТО ТОЧКА, КОТОРАЯ НЕ РАБОТАЕТ), и
- f) изменить новый столбец, который принимает разницу текущего времени и предыдущего времени (по ip).
Эти шаги относятся к комментариям в конце каждой строки.
timedelta <- test %>%
mutate(snap = formatC(snap, width=2, flag=0)) %>% # a)
mutate(fulldateint = paste(hour, snap, sep="")) %>% # b)
mutate(fulldate = as.POSIXct(strptime(fulldateint, "%Y%m%d%H%M"))) %>% # c)
group_by(ip) %>% # d)
mutate(shifted = dplyr::lag(fulldate, default=fulldate)) %>% # e)
mutate(diff = fulldate-shifted) # f)
После мутации данные должны выглядеть так:
ip hour snap fulldateint fulldate shifted diff
<fctr> <dbl> <chr> <chr> <dttm> <dttm> <time>
1 192.168.1.2 2017070700 00 201707070000 2017-07-07 00:00:00 2017-07-07 00:00:00 0 secs
2 192.168.1.2 2017070700 15 201707070015 2017-07-07 00:15:00 2017-07-07 00:00:00 900 secs
3 192.168.1.4 2017070700 00 201707070000 2017-07-07 00:00:00 2017-07-07 00:00:00 0 secs
4 192.168.1.4 2017070701 45 201707070145 2017-07-07 01:45:00 2017-07-07 00:00:00 6300 secs
5 192.168.1.4 2017070702 30 201707070230 2017-07-07 02:30:00 2017-07-07 01:45:00 2700 secs
6 192.168.1.7 2017070700 15 201707070015 2017-07-07 00:15:00 2017-07-07 00:15:00 0 secs
И если бы я мог установить для лага исходное значение по умолчанию, дельта-T всегда была бы равна 0, если у него нет предыдущего значения (что является желаемым результатом).
Однако dplyr::lag(fulldate, default=fulldate)
выдает ошибку
Error in mutate_impl(.data, dots) :
Column `shifted` must be length 2 (the group size) or one, not 3
Это сработает, если я использую Fulldate 1, но тогда я теряю group_by(ip)
результат, который нужен. Можно ли сделать ссылку на задержку своим собственным вводом в dplyr?
Примечание: я бы предпочел, чтобы ответ был с использованием dplyr, а не data.table, если это возможно, поскольку я использовал dplyr в качестве нашей основной библиотеки для изменения данных, но также я хотел бы предложить мистеру Уикхему, чтобы он взял это находится на рассмотрении, если у него действительно нет решения в существующей библиотеке dplyr.
dplyr::lag(fulldate, default = first(fulldate))
? - person Frank   schedule 19.08.2017dput
; см. stackoverflow.com/questions/5963269/, если вы с ним не знакомы. Кстати, я думаю, что аргументуdefault
нужно одно значение, но вместо этого вы дали ему вектор - я думаю, вы упустили этот момент, поэтому я просто пытаюсь его прояснить. Да,first
внутриmutate
послеgroup_by
будет работать над каждой группой отдельно. - person Frank   schedule 19.08.2017