R Academy · Урок

Из длинного формата в широкий с pivot_wider()

Преобразуйте пары ключ—значение обратно в таблицы широкого формата.

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

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

Когда использовать широкий формат

Хотя длинный формат удобен для анализа, широкий формат часто нужен для отчётов, электронных таблиц и некоторых алгоритмов (например, для матриц корреляций). pivot_wider() — обратная функция по отношению к pivot_longer(): она распределяет значения из одного столбца по нескольким новым столбцам.

library(tidyr)

# Long format: one row per student-quarter combination
long_df <- data.frame(
  student = c('Alice','Alice','Alice','Bob','Bob','Bob'),
  quarter = c('Q1','Q2','Q3','Q1','Q2','Q3'),
  score = c(85, 88, 92, 90, 85, 88)
)

print(long_df)
cat('\n', nrow(long_df), 'rows x', ncol(long_df), 'cols')

Основы pivot_wider()

pivot_wider(df, names_from, values_from) преобразует длинный формат в широкий. names_from задаёт столбец, значения которого станут именами новых столбцов; values_from задаёт столбец, значения которого заполнят эти новые столбцы.

library(tidyr)

long_df <- data.frame(
  student = c('Alice','Alice','Alice','Bob','Bob','Bob'),
  quarter = c('Q1','Q2','Q3','Q1','Q2','Q3'),
  score = c(85, 88, 92, 90, 85, 88)
)

wide_df <- pivot_wider(
  long_df,
  names_from = quarter,
  values_from = score
)

print(wide_df)

id_cols — определение ключей строк

id_cols задаёт столбцы, которые однозначно идентифицируют каждую строку в широком результате. По умолчанию dplyr использует все столбцы, не указанные в names_from или values_from. Явное задание этого параметра предотвращает неожиданную группировку.

library(tidyr)

df <- data.frame(
  year = c(2023,2023,2024,2024),
  region = c('East','West','East','West'),
  quarter = c('Q1','Q1','Q1','Q1'),
  revenue = c(100, 200, 120, 220)
)

pivot_wider(
  df,
  id_cols = c(year, quarter),
  names_from = region,
  values_from = revenue
)

values_fill — обработка отсутствующих сочетаний

Если некоторые сочетания id_cols и names_from отсутствуют, соответствующая ячейка будет содержать NA. Используйте values_fill, чтобы заменить такие пропущенные значения значением по умолчанию (например, 0 для подсчётов или сумм).

library(tidyr)

df <- data.frame(
  product = c('A','A','B'),
  channel = c('online','store','online'),
  sales = c(100, 150, 200)
)

# 'B' has no 'store' data — fill with 0
pivot_wider(
  df,
  names_from = channel,
  values_from = sales,
  values_fill = 0
)

names_prefix — добавление префиксов

Используйте names_prefix, чтобы добавить строку в начало имён всех новых столбцов. Это позволяет избежать проблем, если значения в names_from являются числами, а также сделать имена столбцов более информативными.

library(tidyr)

df <- data.frame(
  student = c('Alice','Alice','Bob','Bob'),
  quarter = c(1, 2, 1, 2),
  score = c(85, 90, 78, 82)
)

# Without prefix: columns named '1' and '2' (problematic)
# With prefix: q1, q2
pivot_wider(
  df,
  names_from = quarter,
  values_from = score,
  names_prefix = 'q'
)

Несколько столбцов values_from

Вы можете одновременно преобразовать несколько столбцов со значениями, передав в values_from вектор. В результате столбцы получают имена в формате value_name, объединяющем имя столбца со значением и категорию.

library(tidyr)

df <- data.frame(
  region = c('East','East','West','West'),
  period = c('Q1','Q2','Q1','Q2'),
  revenue = c(100, 120, 200, 210),
  units = c(10, 12, 20, 22)
)

pivot_wider(
  df,
  names_from = period,
  values_from = c(revenue, units)
)

Обработка дубликатов с помощью values_fn

Если для одного сочетания id и name существует несколько значений, pivot_wider не знает, какое из них использовать, и возвращает столбец-список с предупреждением. Используйте values_fn, чтобы решить эту проблему, указав функцию агрегации.

library(tidyr)

# Duplicate rows: Alice has two Q1 scores
df <- data.frame(
  student = c('Alice','Alice','Alice','Bob','Bob'),
  quarter = c('Q1','Q1','Q2','Q1','Q2'),
  score = c(85, 87, 90, 78, 82)
)

# Resolve duplicates by taking the mean
pivot_wider(
  df,
  names_from = quarter,
  values_from = score,
  values_fn = mean
)

values_fn с именованным списком

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

library(tidyr)

df <- data.frame(
  region = c('East','East','West','West'),
  period = c('Q1','Q1','Q1','Q1'),
  revenue = c(100, 120, 200, 210),
  orders = c(10, 12, 20, 22)
)

pivot_wider(
  df,
  names_from = period,
  values_from = c(revenue, orders),
  values_fn = list(revenue = sum, orders = sum)
)

Создание перекрёстных таблиц

Перекрёстную таблицу (таблицу сопряжённости) в виде таблицы данных легко создать с помощью pivot_wider() после подсчёта с использованием dplyr::count(). Это объединяет возможности обоих пакетов для анализа частот.

library(tidyr)
library(dplyr)

survey <- data.frame(
  dept = c('HR','HR','Eng','Eng','HR','Eng'),
  response = c('Yes','No','Yes','Yes','Yes','No')
)

survey %>%
  count(dept, response) %>%
  pivot_wider(
    names_from = response,
    values_from = n,
    values_fill = 0
  )

Обратное преобразование: длинный формат → широкий → длинный

Понимание обратной связи между pivot_longer() и pivot_wider() помогает обнаруживать ошибки. После обратного преобразования (длинный формат → широкий → длинный) должны получиться исходные данные (за исключением порядка строк и преобразований типов).

library(tidyr)

original_long <- data.frame(
  id = c(1,1,2,2),
  key = c('a','b','a','b'),
  value = c(10, 20, 30, 40)
)

# Go wide
wide <- pivot_wider(original_long, names_from=key, values_from=value)
print(wide)

# Go long again
pivot_longer(wide, -id, names_to='key', values_to='value')

Практический пример: отчёт с оценками

Типичный сценарий: взять длинную таблицу с результатами тестов и преобразовать её в отчётную таблицу, где строки соответствуют учащимся, а столбцы — предметам. Объедините это с dplyr::arrange() и rename(), чтобы получить аккуратный результат, готовый для представления.

library(tidyr)
library(dplyr)

scores <- data.frame(
  student = c('Alice','Alice','Bob','Bob','Carol','Carol'),
  subject = c('Math','Science','Math','Science','Math','Science'),
  score = c(92, 88, 85, 91, 79, 83)
)

scores %>%
  pivot_wider(names_from=subject, values_from=score) %>%
  mutate(average = round((Math + Science) / 2, 1)) %>%
  arrange(desc(average))

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

Что произойдёт при вызове pivot_wider(), если для одного сочетания id и name существует несколько значений?

Итоги: pivot_wider()

Главные выводы о преобразовании из длинного формата в широкий:

  • pivot_wider(names_from, values_from) преобразует столбец с ключами в несколько новых столбцов
  • id_cols указывает, какие столбцы идентифицируют каждую строку
  • values_fill = 0 (или любое скалярное значение) заполняет отсутствующие сочетания
  • names_prefix добавляет строку в начало имени, предотвращая появление числовых или неоднозначных имён столбцов
  • values_fn разрешает дубликаты значений ячеек с помощью функции агрегации
  • Передайте в values_from вектор, чтобы одновременно преобразовать несколько столбцов со значениями
  • Используйте после count() для эффективного создания перекрёстных таблиц
library(tidyr)
library(dplyr)

data.frame(
  region = c('East','East','West','West'),
  metric = c('revenue','units','revenue','units'),
  value = c(100, 10, 200, 20)
) %>%
  pivot_wider(
    names_from = metric,
    values_from = value,
    values_fill = 0
  ) %>%
  mutate(revenue_per_unit = revenue / units)
Можно начать бесплатно

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

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

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

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

Урок «Из длинного формата в широкий с pivot_wider()» бесплатный?

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

Чему я научусь в уроке «Из длинного формата в широкий с pivot_wider()»?

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

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

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

Сколько времени занимает урок «Из длинного формата в широкий с pivot_wider()»?

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

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

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

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

  1. Из широкого формата в длинный с pivot_longer()
  2. Из длинного формата в широкий с pivot_wider()
  3. separate() и unite() для строковых столбцов
  4. Вложенные и развёрнутые таблицы данных
← Назад к R Academy