Работа с сгруппированным набором данных в R

У меня есть набор данных, как:

+ ---- + ------- + --------- + ---------- + - +
| id | время | событие | Timediff | |
+ ---- + ------- + --------- + ---------- + - +
| 1 | 15.00 | установить | - | |
| 1 | 15.30 | продажа | 00.30    |  |
|  1 | 16.00 | продажа | 00.30    |  |
|  2 | 15.00 | продажа | -        |  |
|  2 | 15.30 | продажа | 0,30     |  |
|  3 | 16.00 | установить | -        |  |
|  4 | 15.00 | установить | - | |
| 5 | 13.00 | установить | -        |  |
|  5 | 14.00 | продажа | 01.00 | |
+ ---- + ------- + --------- + ---------- + - +

Я хочу очистить этот набор данных: я хочу исключить идентификаторы, для которых первые (и следующие n..) события являются продажами, а не установками. Я хочу исключить идентификаторы, для которых есть установка, но нет продаж (эти идентификаторы действительно уникальны)

Получив наконец результат как:

+ ---- + ------- + --------- + ---------- +
| id | время | событие | Timediff |
+ ---- + ------- + --------- + ---------- +
| 1 | 15.00 | установить | - |
| 1 | 15.30 | продажа | 0,30     |
|  1 | 16.00 | продажа | 0,30 |
| 5 | 13.00 | установить | -        |
|  5 | 14.00 | продажа | 01.00 |
+ ---- + ------- + --------- + ---------- +

Как я могу сделать это в R? Есть ли какой-то конкретный пакет для манипулирования данными, или я могу просто использовать формулы? Должен ли я использовать tapply?

1 ответ

Решение

Основываясь на примере, мы можем сгруппировать по 'id' и filter столбец "событие", который имеет first элемент как "установить" и 2-й как "продажа", чтобы получить ожидаемый результат.

df1 %>%
  group_by(id) %>%
  filter(first(event)=='install' & event[2L]=='sale')
    id  time   event timediff
#  (int) (dbl)   (chr)    (dbl)
#1     1  15.0 install       NA
#2     1  15.3    sale      0.3
#3     1  16.0    sale      0.3
#4     5  13.0 install       NA
#5     5  14.0    sale      1.0

Или, если все элементы, кроме первого, должны быть "продажа", мы создаем логическую переменную ("ind"), сравнивая first элемент как "установить" и последующие элементы как "продажа" (используя lead), затем filter группы где all "ИНД" - ИСТИНА. При необходимости мы можем удалить столбец "ind", используя select,

 df1 %>% 
     group_by(id) %>%
     mutate(ind= first(event)=='install' & lead(event, default='sale')=='sale') %>%
     filter(all(ind)) %>% 
     ungroup() %>% 
     select(-ind)

Или мы можем использовать data.table., сгруппированные по 'id', if количество строк больше 1 (.N >1), первым элементом является 'install' (event[1L]=='install') а также all остальные элементы - "продажа", тогда мы получим Подмножество Data.table (.SD).

library(data.table)
setDT(df1)[, if(.N > 1 & event[1L]=='install' & all(event[2:.N]=='sale')) .SD, by = id]
#   id time   event timediff
#1:  1 15.0 install       NA
#2:  1 15.3    sale      0.3
#3:  1 16.0    sale      0.3
#4:  5 13.0 install       NA
#5:  5 14.0    sale      1.0
Другие вопросы по тегам