Поиск…


Вступление

Объединение объединяет две таблицы, содержащие соответствующие столбцы. Термин охватывает широкий диапазон операций, по сути, все, кроме добавления двух таблиц . «Слияние» - синоним. Введите ?`[.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 .

Преимущества использования отдельных таблиц

Преимущества этой структуры описаны в статье о аккуратных данных, но в этом контексте:

  1. Отслеживание отсутствующих данных. Только строки, которые совпадают в слиянии, получают задание. У нас нет данных для geo_id == "MO" выше, поэтому его переменными являются NA в нашей финальной таблице. Если мы увидим недостающие данные, как это неожиданно, мы можем отследить его обратно к отсутствующему наблюдению в таблице geoDT и выяснить, есть ли у нас проблема с данными, которую можно решить.

  2. Понятность. При построении нашей статистической модели может быть важно иметь в виду, что budget постоянен для каждого исполнителя. В общем, понимание структуры данных платит дивиденды.

  3. Размер памяти. Может существовать большое количество атрибутов исполнителей и местоположений, которые не попадают в статистическую модель. Таким образом, нам не нужно включать их в (возможно, массивную) таблицу, используемую для анализа.

Программно определяющие столбцы

Если в 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow