data.table
Объединяет и объединяет
Поиск…
Вступление
?`[.data.table`
для официальных документов.
Синтаксис
- x [i, on, j]
# join: data.table x & data.table или список i - x [! i, on, j]
# anti-join
замечания
Работа с таблицами с ключами
Если x
& i
имеет ключ или x
имеет ключевое значение для совпадения первых столбцов i
, то on
можно пропустить как x[i]
.
Обнаружение неоднозначных имен столбцов
В j
из x[i, on, j]
столбцы i
можно отнести к i.*
Префиксам.
Группировка по подмножествам
В j
из x[i, on, j, by=.EACHI]
j
вычисляется для каждой строки i
.
Это единственное значение, by
стоит использовать. Для любого другого значения столбцы i
недоступны.
Обновить значения в соединении
Когда данные «аккуратные», они часто объединяются в несколько таблиц. Чтобы объединить данные для анализа, нам нужно «обновить» одну таблицу значениями из другой.
Например, у нас могут быть данные о продажах для выступлений, где атрибуты исполнителя (их бюджета) и местоположения (его населения) хранятся в отдельных таблицах:
set.seed(1)
mainDT = data.table(
p_id = rep(LETTERS[1:2], c(2,4)),
geo_id = sample(rep(state.abb[c(1,25,50)], 3:1)),
sales = sample(100, 6)
)
pDT = data.table(id = LETTERS[1:2], budget = c(60, 75))
geoDT = data.table(id = state.abb[c(1,50)], pop = c(100, 200))
mainDT # sales data
# p_id geo_id sales
# 1: A AL 95
# 2: A WY 66
# 3: B AL 62
# 4: B MO 6
# 5: B AL 20
# 6: B MO 17
pDT # performer attributes
# id budget
# 1: A 60
# 2: B 75
geoDT # location attributes
# id pop
# 1: AL 100
# 2: WY 200
Когда мы будем готовы сделать некоторый анализ, нам нужно взять переменные из этих других таблиц:
DT = copy(mainDT)
DT[pDT, on=.(p_id = id), budget := i.budget]
DT[geoDT, on=.(geo_id = id), pop := i.pop]
# p_id geo_id sales budget pop
# 1: A AL 95 60 100
# 2: A WY 66 60 200
# 3: B AL 62 75 100
# 4: B MO 6 75 NA
# 5: B AL 20 75 100
# 6: B MO 17 75 NA
copy
берется во избежание загрязнения исходных данных, но мы можем работать непосредственно на mainDT
.
Преимущества использования отдельных таблиц
Преимущества этой структуры описаны в статье о аккуратных данных, но в этом контексте:
Отслеживание отсутствующих данных. Только строки, которые совпадают в слиянии, получают задание. У нас нет данных для
geo_id == "MO"
выше, поэтому его переменными являютсяNA
в нашей финальной таблице. Если мы увидим недостающие данные, как это неожиданно, мы можем отследить его обратно к отсутствующему наблюдению в таблицеgeoDT
и выяснить, есть ли у нас проблема с данными, которую можно решить.Понятность. При построении нашей статистической модели может быть важно иметь в виду, что
budget
постоянен для каждого исполнителя. В общем, понимание структуры данных платит дивиденды.Размер памяти. Может существовать большое количество атрибутов исполнителей и местоположений, которые не попадают в статистическую модель. Таким образом, нам не нужно включать их в (возможно, массивную) таблицу, используемую для анализа.
Программно определяющие столбцы
Если в pDT
много столбцов, но мы хотим только выбрать несколько, мы можем использовать
p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]
(p_cols) :=
необходимы, как указано в документе о создании столбцов .
Обор присоединиться
# example data
a = data.table(id = c(1L, 1L, 2L, 3L, NA_integer_), x = 11:15)
# id x
# 1: 1 11
# 2: 1 12
# 3: 2 13
# 4: 3 14
# 5: NA 15
b = data.table(id = 1:2, y = -(1:2))
# id y
# 1: 1 -1
# 2: 2 -2
Интуиция
Подумайте о x[i]
как выборе подмножества x
для каждой строки i
. Этот синтаксис отображает матрицу подмножества в базе R и согласуется с первым аргументом, означающим «где», в DT[where, select|update|do, by]
.
Интересно, почему этот новый синтаксис стоит изучать, поскольку merge(x,i)
все еще работает с data.tables. Короткий ответ заключается в том, что мы обычно хотим слиться, а затем делать что-то еще. Синтаксис x[i]
кратко фиксирует этот шаблон использования, а также позволяет более эффективно вычислять. Для более подробного объяснения читайте FAQ 1.12 и 2.14 .
Обработка многострочных строк
По умолчанию, каждая строка a
согласовании каждой строки b
возвращается:
a[b, on="id"]
# id x y
# 1: 1 11 -1
# 2: 1 12 -1
# 3: 2 13 -2
Это можно настроить с помощью mult
:
a[b, on="id", mult="first"]
# id x y
# 1: 1 11 -1
# 2: 2 13 -2
Работа с непревзойденными строками
По умолчанию в a
все еще появляются несогласованные строки:
b[a, on="id"]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
# 4: 3 NA 14
# 5: NA NA 15
Чтобы скрыть их, используйте nomatch
:
b[a, on="id", nomatch=0]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
Обратите внимание, что x[i]
попытается сопоставить NA в i
.
Возвращаемые совпадения
Чтобы подсчитать количество совпадений для каждой строки i
, используйте .N
и by=.EACHI
.
b[a, on="id", .N, by=.EACHI]
# id N
# 1: 1 1
# 2: 1 1
# 3: 2 1
# 4: 3 0
# 5: NA 0