Объединение нескольких таблиц в dplyr
Освойте inner_join, left_join, right_join, full_join и anti_join.
«Объединение нескольких таблиц в 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 — локальная установка не требуется.
Все уроки этого курса
- Сгруппированные сводки и group_by()
- Оконные функции: lag, lead, cumsum
- Объединение нескольких таблиц в dplyr
- Аккуратное вычисление: {{ }} и .data