Удаляйте дубликаты при наложении особых условий в R

У меня есть следующая табличка (показаны только первые 10 строк из ~ 2 миллионов):

   ID              STATUS     NUMBER  FUNCTION LASTMODIFIED         AMOUNT YEAR   MONTH  DAY  
   <chr>           <chr>      <chr>   <chr>    <dttm>               <dbl>  <int>  <int>  <int>
 1 oQYKPAsu9j8AAAF APPROVED   "008"   CREDIT   2022-03-15 15:16:26  2401   2022   3      15   
 2 hhoKPAs_fjUAAAF APPROVED   "101"   CREDIT   2022-03-15 15:15:23  959    2022   3      15   
 3 Ip8KPAsj__4AAAF DENIED     "99"    LIMIT    2022-03-15 15:14:06  0      2022   3      15   
 4 wa4KPAstYwIAAAF DENIED     "99"    LIMIT    2022-03-15 15:13:36  0      2022   3      15   
 5 GucKPAssdaUAAAF APPROVED   "101"   LIMIT    2022-03-15 15:13:21  1084   2022   3      15   
 6 a6AKPAtAsx4AAAF DENIED     "101"   CREDIT   2022-03-15 15:12:02  699    2022   3      15   
 7 a6AKPAtAsx4AAAF DENIED     "101"   CREDIT   2022-03-15 15:12:34  699    2022   3      15   
 8 F4kKPAss7OAAAAF APPROVED   "101"   CREDIT   2022-03-15 15:10:25  3167   2022   3      15   
 9 MK4KPAstiEYAAAF DENIED     "99"    LIMIT    2022-03-15 15:08:46  0      2022   3      15   
10 .nUKPAs.crIAAAF APPROVED    NA     CREDIT   2022-03-15 15:08:35  58     2022   3      15   

Здесь показаны некоторые операции, которые разные пользователи выполняли на веб-сайте, каждый идентификатор — это один уникальный клиент. Я хочу удалить повторяющиеся записи, которые произошли в течение x минут друг от друга. Таким образом, ясно, что в приведенных выше данных должна быть сохранена только строка 6 или 7 (предпочтительно первая). Есть ли аккуратный способ tidyverse/dplyr сделать это?

Моей первой мыслью было проигнорировать столбец LASTMODIFIED и использовать dg &>& filter(!duplicate()), но это не сделает то, что я хочу.

"в течение х минут" и "игнорировать LASTMODIFIED" совершенно несовместимы.
r2evans 22.03.2022 14:16

Ты прав. Я забыл добавить, что я вычислил разницу в минутах между двумя строками (где все остальные поля одинаковы) и поместил результат в новый столбец.

Parseval 22.03.2022 14:18

скажем, x = 10 минут. Что должно произойти, когда 3 события происходят через 7 минут друг после друга. Итак, A = 0, B = 7, C = 14 минут. Должны ли быть удалены только B или B и C?

Wimpel 22.03.2022 14:18

@Wimpel - таких случаев нет, так как зарегистрировано максимум два. В качестве альтернативы можно ограничить дублирование в один и тот же день. Поэтому, если в один и тот же день есть несколько дубликатов, сохраняется только один. Чтобы ответить на ваш обновленный вопрос: B и C следует удалить

Parseval 22.03.2022 14:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что данные уже упорядочены по LASTMODIFIED (по крайней мере, в каждой группе), тогда

xseconds <- 600
dat %>%
  group_by(across(-LASTMODIFIED)) %>%
  filter(c(TRUE, as.numeric(diff(LASTMODIFIED), units = "secs") > xseconds)) %>%
  ungroup()
# # A tibble: 9 x 9
#   ID              STATUS   NUMBER FUNCTION LASTMODIFIED        AMOUNT  YEAR MONTH   DAY
#   <chr>           <chr>     <int> <chr>    <dttm>               <int> <int> <int> <int>
# 1 oQYKPAsu9j8AAAF APPROVED      8 CREDIT   2022-03-15 15:16:26   2401  2022     3    15
# 2 hhoKPAs_fjUAAAF APPROVED    101 CREDIT   2022-03-15 15:15:23    959  2022     3    15
# 3 Ip8KPAsj__4AAAF DENIED       99 LIMIT    2022-03-15 15:14:06      0  2022     3    15
# 4 wa4KPAstYwIAAAF DENIED       99 LIMIT    2022-03-15 15:13:36      0  2022     3    15
# 5 GucKPAssdaUAAAF APPROVED    101 LIMIT    2022-03-15 15:13:21   1084  2022     3    15
# 6 a6AKPAtAsx4AAAF DENIED      101 CREDIT   2022-03-15 15:12:02    699  2022     3    15
# 7 F4kKPAss7OAAAAF APPROVED    101 CREDIT   2022-03-15 15:10:25   3167  2022     3    15
# 8 MK4KPAstiEYAAAF DENIED       99 LIMIT    2022-03-15 15:08:46      0  2022     3    15
# 9 .nUKPAs.crIAAAF APPROVED     NA CREDIT   2022-03-15 15:08:35     58  2022     3    15

Данные

dat <- structure(list(ID = c("oQYKPAsu9j8AAAF", "hhoKPAs_fjUAAAF", "Ip8KPAsj__4AAAF", "wa4KPAstYwIAAAF", "GucKPAssdaUAAAF", "a6AKPAtAsx4AAAF", "a6AKPAtAsx4AAAF", "F4kKPAss7OAAAAF", "MK4KPAstiEYAAAF", ".nUKPAs.crIAAAF"), STATUS = c("APPROVED", "APPROVED", "DENIED", "DENIED", "APPROVED", "DENIED", "DENIED", "APPROVED", "DENIED", "APPROVED"), NUMBER = c(8L, 101L, 99L, 99L, 101L, 101L, 101L, 101L, 99L, NA), FUNCTION = c("CREDIT", "CREDIT", "LIMIT", "LIMIT", "LIMIT", "CREDIT", "CREDIT", "CREDIT", "LIMIT", "CREDIT" ), LASTMODIFIED = structure(c(1647371786, 1647371723, 1647371646, 1647371616, 1647371601, 1647371522, 1647371554, 1647371425, 1647371326, 1647371315), class = c("POSIXct", "POSIXt"), tzone = ""), AMOUNT = c(2401L, 959L, 0L, 0L, 1084L, 699L, 699L, 3167L, 0L, 58L), YEAR = c(2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L), MONTH = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), DAY = c(15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L)), class = "data.frame", row.names = c("1", "2",  "3", "4", "5", "6", "7", "8", "9", "10"))

То есть он удаляет только те дубликаты, которые отличаются менее чем за 600 секунд? Я пытался сделать это, когда я поставил xseconds = 10, и он все еще удалял строку 6. Это НЕ должно удалять ее, верно? С 15:12:02 до 15:10:25 > 10 секунд.

Parseval 22.03.2022 15:08

Проверьте еще раз, пожалуйста... почему-то не осталась правка по смене хардкода 600 на xseconds...

r2evans 22.03.2022 16:48

Другие вопросы по теме