#r #user-defined-functions #aggregation #lapply
#r #определяемые пользователем-функции #агрегирование #lapply
Вопрос:
Я работаю с пакетом data.table. У меня есть таблица данных, которая представляет действия пользователей на веб-сайте. Предположим, что каждый пользователь может посетить веб-сайт и выполнить на нем несколько действий. Моя исходная таблица данных содержит действия (каждая строка — это действие), и я хочу объединить эту информацию в новую таблицу данных, сгруппированную по посещениям пользователей (каждое посещение имеет уникальный идентификатор). Есть некоторые поля, которые являются общими для действий одного и того же посещения — например, имя пользователя, статус пользователя, номер посещения и т.д. По крайней мере, одно из действий каждого посещения содержит эту информацию (не обязательно все действия). Я хочу извлекать для каждого посещения (= группы действий с одинаковым идентификатором посещения) значение этого поля и присваивать ему значение посещения в новой таблице данных посещений. Например, если у меня есть следующая исходная таблица данных:
VisitID ActionNum UserName UserStatus VisitNum ActionType
aaaaaaa 1 John Active 5 x
aaaaaaa 2 Active y
aaaaaaa 3 John 5 z
bbbbbbb 1 NonActive w
bbbbbbb 2 Dan 7 t
Я хочу иметь таблицу данных посещений следующим образом:
VisitID UserName UserStatus VisitNum
aaaaaaa John Active 5
bbbbbbb Dan NonActive 7
Я создал функцию, которая работает с подмножеством таблицы данных (только строки посещения) и полем, и эта функция должна применяться к нескольким полям (имя пользователя, UserStatus, VisitNum).
getGeneralField<- function(visitDT,field){
vec = visitDT[,get(field)]
return (unique(vec[vec != ""])[1])
}
Проблема в том, что каждая попытка применить эту функцию.SD, когда by=VisitID приводит к чему-то отличному от того, что я планировал… Каков наилучший способ сделать это? Я использовал !=»», чтобы избежать пустых ячеек.
Комментарии:
1. Я думаю, что вам нужно
dt[, lapply(.SD, function(x) x[nzchar(x)][1]), by = VisitID, .SDcols = 3:5]
2. Спасибо! Работает отлично!
Ответ №1:
Мы указываем интересующие столбцы .SDcols
, сгруппированные по ‘VisitID’, перебираем столбцы в .SDcols
( lapply(.SD, ...
) и получаем первый непустой элемент
dt[, lapply(.SD, function(x) x[nzchar(x)][1]), by = VisitID, .SDcols = 3:5]