Работа с сгруппированным набором данных в 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