Таблица данных — применить ту же функцию к нескольким столбцам для создания новых столбцов таблицы данных

#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]