R Academy · Урок

Объединение нескольких таблиц в dplyr

Освойте inner_join, left_join, right_join, full_join и anti_join.

Урок 3 из 413 шагов

«Объединение нескольких таблиц в dplyr» — бесплатный урок R Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Зачем объединять таблицы?

Реальные данные редко хранятся в одной таблице. Реляционные базы данных распределяют информацию по нескольким таблицам, чтобы избежать повторений. Объединения позволяют объединять таблицы на основе общих ключей. В dplyr предусмотрены функции объединения в стиле SQL с понятным и удобным синтаксисом.

library(dplyr)

# Two related tables
orders <- data.frame(
  order_id = 1:4,
  customer_id = c(1, 2, 1, 3),
  amount = c(250, 180, 320, 90)
)

customers <- data.frame(
  customer_id = 1:3,
  name = c('Alice','Bob','Carol'),
  city = c('NYC','LA','Chicago')
)

print(orders)
print(customers)

inner_join() — только совпадающие строки

inner_join(x, y, by='key') возвращает только те строки, для которых ключ существует в обеих таблицах. Строки, для которых нет соответствия в другой таблице, удаляются. Это наиболее распространённый тип объединения.

library(dplyr)

orders <- data.frame(
  order_id = 1:4,
  customer_id = c(1, 2, 1, 99),
  amount = c(250, 180, 320, 90)
)

customers <- data.frame(
  customer_id = c(1, 2, 3),
  name = c('Alice','Bob','Carol')
)

# customer_id = 99 in orders has no match => dropped
# customer_id = 3 in customers has no match => dropped
inner_join(orders, customers, by = 'customer_id')

left_join() — сохранить все строки слева

left_join(x, y, by='key') сохраняет все строки из x и добавляет соответствующие данные из y. Для строк x, которым не соответствует ни одна строка y, в столбцах y устанавливается NA. Результат определяется левой таблицей.

library(dplyr)

orders <- data.frame(
  order_id = 1:4,
  customer_id = c(1, 2, 1, 99),
  amount = c(250, 180, 320, 90)
)

customers <- data.frame(
  customer_id = c(1, 2, 3),
  name = c('Alice','Bob','Carol')
)

# Order with customer_id=99 is kept, name = NA
left_join(orders, customers, by = 'customer_id')

right_join() — сохранить все строки справа

right_join(x, y, by='key') сохраняет все строки из y. Для строк y, которым не соответствует ни одна строка x, в столбцах x устанавливается NA. Это зеркальный вариант left_join() — он используется реже, поскольку порядок таблиц можно поменять.

library(dplyr)

orders <- data.frame(
  order_id = c(1, 2),
  customer_id = c(1, 2),
  amount = c(250, 180)
)

customers <- data.frame(
  customer_id = c(1, 2, 3),
  name = c('Alice','Bob','Carol')
)

# Carol (customer_id=3) has no orders => NA for order columns
right_join(orders, customers, by = 'customer_id')

full_join() — сохранить все строки

full_join(x, y, by='key') сохраняет каждую строку из обеих таблиц. Для строк без соответствия с любой стороны в столбцах другой таблицы устанавливается NA. Используйте этот вариант, когда нельзя потерять ни одной записи.

library(dplyr)

q1 <- data.frame(product = c('A','B','C'), q1_sales = c(100, 200, 150))
q2 <- data.frame(product = c('A','C','D'), q2_sales = c(120, 160, 90))

# D appears only in q2, B only in q1 => both kept
full_join(q1, q2, by = 'product')

anti_join() — найти несовпадения

anti_join(x, y, by='key') возвращает строки из x, для которых нет соответствия в y. Столбцы из y не добавляются. Это удобно для поиска записей-сирот, заказов без соответствий или элементов, отсутствующих в справочной таблице.

library(dplyr)

all_employees <- data.frame(
  id = 1:5,
  name = c('Alice','Bob','Carol','Dave','Eve')
)

trained <- data.frame(id = c(1, 3, 5))

# Who has NOT completed training?
anti_join(all_employees, trained, by = 'id')

semi_join() — отфильтровать по соответствию

semi_join(x, y, by='key') возвращает строки из x, для которых есть соответствие в y, но НЕ добавляет столбцы y. Это похоже на inner_join(), однако возвращаются только столбцы x — такой вариант удобен как шаг фильтрации.

library(dplyr)

products <- data.frame(
  id = 1:5,
  name = c('Widget','Gadget','Donut','Gizmo','Sprocket'),
  price = c(9.99, 24.99, 1.99, 14.99, 4.99)
)

ordered_products <- data.frame(id = c(1, 3, 5))

# Products that appear in at least one order
semi_join(products, ordered_products, by = 'id')

Объединение по столбцам с разными именами

Если ключевые столбцы в x и y называются по-разному, используйте синтаксис by = c('x_col' = 'y_col'). Он сопоставляет имя столбца в левой таблице с соответствующим именем столбца в правой.

library(dplyr)

orders <- data.frame(
  order_id = 1:3,
  user_id = c(10, 20, 10),
  amount = c(100, 200, 150)
)

users <- data.frame(
  id = c(10, 20, 30),
  username = c('alice','bob','carol')
)

# orders.user_id matches users.id
left_join(orders, users, by = c('user_id' = 'id'))

Объединение по нескольким ключам

Объединять таблицы по нескольким столбцам можно, передав в by вектор. Для объединения строки должны совпасть по всем указанным столбцам. Это позволяет работать с составными ключами, в которых ни один отдельный столбец не является уникальным.

library(dplyr)

actual <- data.frame(
  year = c(2023, 2023, 2024, 2024),
  quarter = c('Q1','Q2','Q1','Q2'),
  sales = c(100, 120, 130, 150)
)

target <- data.frame(
  year = c(2023, 2023, 2024, 2024),
  quarter = c('Q1','Q2','Q1','Q2'),
  target = c(110, 115, 125, 145)
)

inner_join(actual, target, by = c('year', 'quarter'))

Цепочка из нескольких объединений

Можно объединить несколько операций в одну цепочку, используя оператор конвейера. Постепенно создавайте денормализованное представление, добавляя на каждом шаге информацию из нескольких справочных таблиц.

library(dplyr)

orders <- data.frame(order_id=1:3, cust_id=c(1,2,1), prod_id=c(10,10,20))
customers <- data.frame(cust_id=1:2, name=c('Alice','Bob'))
products <- data.frame(prod_id=c(10,20), product=c('Widget','Gadget'))

orders %>%
  left_join(customers, by = 'cust_id') %>%
  left_join(products, by = 'prod_id')

Обработка дублирующихся столбцов

Если в обеих таблицах есть столбцы с одинаковыми именами (кроме ключевого столбца объединения), dplyr добавляет суффиксы .x и .y. Их можно настроить с помощью аргумента suffix, а затем выбрать нужные столбцы или переименовать их.

library(dplyr)

current <- data.frame(id=1:3, value=c(10,20,30), date=Sys.Date())
historic <- data.frame(id=1:3, value=c(8,22,28), date=Sys.Date()-365)

# Both have 'value' and 'date' columns
result <- inner_join(current, historic, by='id',
                     suffix=c('_current','_historic'))
print(names(result))

Быстрая проверка

Какое объединение dplyr возвращает только строки из левой таблицы, которым не соответствует ни одна строка в правой?

Итоги: объединения в dplyr

Главное о работе с несколькими таблицами в dplyr:

  • inner_join() — только совпадающие строки из обеих таблиц
  • left_join() — все строки из левой таблицы; NA при отсутствии соответствия в правой
  • right_join() — все строки из правой таблицы; NA при отсутствии соответствия в левой
  • full_join() — все строки из обеих таблиц; NA при отсутствии соответствия
  • anti_join() — строки x БЕЗ соответствия в y (инструмент фильтрации)
  • semi_join() — строки x С соответствием в y (инструмент фильтрации)
  • Используйте by = c('x_col' = 'y_col') для столбцов с разными именами
  • Используйте вектор для составных ключей: by = c('year', 'quarter')
library(dplyr)

# Chain of joins: the typical real-world pattern
orders <- data.frame(oid=1:3, cid=c(1,2,1), pid=c(10,20,10))
customers <- data.frame(cid=1:2, name=c('Alice','Bob'))
products <- data.frame(pid=c(10,20), name=c('Widget','Gadget'), price=c(9.99,19.99))

orders %>%
  inner_join(customers, by='cid') %>%
  inner_join(products, by='pid', suffix=c('','_product')) %>%
  select(oid, name, name_product, price)
Можно начать бесплатно

Изучай R с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
43
Уроки
159

Часто задаваемые вопросы

Урок «Объединение нескольких таблиц в dplyr» бесплатный?

Да — полный текст урока «Объединение нескольких таблиц в dplyr» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Объединение нескольких таблиц в dplyr»?

Освойте inner_join, left_join, right_join, full_join и anti_join. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Объединение нескольких таблиц в dplyr»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Сгруппированные сводки и group_by()
  2. Оконные функции: lag, lead, cumsum
  3. Объединение нескольких таблиц в dplyr
  4. Аккуратное вычисление: {{ }} и .data
← Назад к R Academy