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

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

+----+-------+---------+----------+--+
| id | time  |  event  | timediff |  |
+----+-------+---------+----------+--+
|  1 | 15.00 | install | -        |  |
|  1 | 15.30 | sale    | 00.30    |  |
|  1 | 16.00 | sale    | 00.30    |  |
|  2 | 15.00 | sale    | -        |  |
|  2 | 15.30 | sale    | 0.30     |  |
|  3 | 16.00 | install | -        |  |
|  4 | 15.00 | install | -        |  |
|  5 | 13.00 | install | -        |  |
|  5 | 14.00 | sale    | 01.00    |  |
+----+-------+---------+----------+--+

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

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

+----+-------+---------+----------+
| id | time  |  event  | timediff |
+----+-------+---------+----------+
|  1 | 15.00 | install | -        |
|  1 | 15.30 | sale    | 0.30     |
|  1 | 16.00 | sale    | 0.30     |
|  5 | 13.00 | install | -        |
|  5 | 14.00 | sale    | 01.00    |
+----+-------+---------+----------+

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


person xxxvincxxx    schedule 03.11.2015    source источник
comment
Что-нибудь, что вы уже пробовали сами? Почему это не сработало?   -  person Heroka    schedule 03.11.2015
comment
В будущем попробуйте опубликовать код для воспроизведения ваших данных, так как вышеприведенный табличный формат не может быть легко преобразован в объект R.   -  person nrussell    schedule 03.11.2015


Ответы (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

Или, если все элементы, кроме первого, должны быть «продажа», мы создаем логическую переменную («инд»), сравнивая элемент first как «установка» и последующие элементы как «продажа» (используя lead), затем filter группирует, где all "ind" ИСТИНА. При необходимости мы можем удалить столбец «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), первый элемент «установить» (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
person akrun    schedule 03.11.2015
comment
оно работает! но я не очень хорошо понимаю логику параметра [2L]. Что это значит? - person xxxvincxxx; 03.11.2015