0Pricing
R Academy · Урок

Оконные функции: lag, lead, cumsum

Вычисляйте накопительные итоги, смещения и кумулятивные агрегаты внутри групп.

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

Что такое оконные функции?

Оконные функции вычисляют значения относительно текущей строки, не сворачивая данные. В отличие от summarize(), они сохраняют все строки. В dplyr оконные функции используются внутри mutate(), часто после group_by().

library(dplyr)

# Monthly revenue — we want to compare each month to previous
df <- data.frame(
  month = 1:6,
  revenue = c(100, 120, 95, 140, 160, 130)
)
print(df)

lag() — значение предыдущей строки

lag(x, n=1) возвращает значение из строки, находящейся на n строк до текущей. Для первой строки или первых строк будет получено NA. Функция идеально подходит для вычисления изменений от периода к периоду.

library(dplyr)

df <- data.frame(
  month = 1:6,
  revenue = c(100, 120, 95, 140, 160, 130)
)

df %>%
  mutate(
    prev_revenue = lag(revenue),
    change = revenue - lag(revenue),
    pct_change = round(100 * (revenue - lag(revenue)) / lag(revenue), 1)
  )

lead() — значение следующей строки

lead(x, n=1) возвращает значение из строки, находящейся на n строк после текущей. Для последней строки или последних строк будет получено NA. Функция полезна для сравнения текущего значения с будущими.

library(dplyr)

df <- data.frame(
  month = 1:5,
  revenue = c(100, 120, 95, 140, 160)
)

df %>%
  mutate(
    next_month = lead(revenue),
    next_2_months = lead(revenue, n = 2),
    will_increase = revenue < lead(revenue)
  )

cumsum() и cumprod()

cumsum(x) вычисляет нарастающий итог (накопительную сумму). cumprod(x) вычисляет накопительное произведение. Обе функции относятся к базовым функциям R и без проблем работают внутри mutate().

library(dplyr)

df <- data.frame(
  month = 1:6,
  revenue = c(100, 120, 95, 140, 160, 130)
)

df %>%
  mutate(
    running_total = cumsum(revenue),
    growth_factor = round(cumprod(1 + (revenue - 100) / 100), 3)
  )

cummax() и cummin()

cummax(x) отслеживает нарастающий максимум — наибольшее значение, встреченное к текущему моменту. cummin(x) отслеживает нарастающий минимум. Это полезно для отслеживания исторических максимумов и минимумов и анализа просадок.

library(dplyr)

df <- data.frame(
  day = 1:7,
  price = c(50, 52, 48, 55, 53, 58, 56)
)

df %>%
  mutate(
    all_time_high = cummax(price),
    all_time_low = cummin(price),
    drawdown_from_high = price - cummax(price)
  )

Ранжирование с row_number()

row_number() присваивает каждой строке целочисленный ранг. При использовании после group_by() ранжирование выполняется внутри каждой группы. При совпадении значений ранги идут последовательно в порядке появления строк.

library(dplyr)

sales <- data.frame(
  region = c('East','East','East','West','West','West'),
  rep = c('Alice','Bob','Carol','Dave','Eve','Frank'),
  revenue = c(200, 150, 180, 120, 190, 160)
)

sales %>%
  group_by(region) %>%
  mutate(rank = row_number(desc(revenue))) %>%
  arrange(region, rank)

ntile() — распределение по группам

ntile(x, n) делит данные на n примерно равных групп и возвращает номер группы (1 = наименьшие значения). Это полезно для создания квартилей, децилей или процентильных групп.

library(dplyr)

df <- data.frame(
  customer = paste0('C', 1:10),
  spend = c(50, 200, 75, 300, 125, 450, 25, 175, 100, 350)
)

df %>%
  mutate(
    quartile = ntile(spend, 4),
    decile = ntile(spend, 10)
  ) %>%
  arrange(spend)

percent_rank() — относительное положение

percent_rank(x) возвращает ранг каждого значения как долю от 0 до 1. Минимальное значение получает 0, максимальное — 1. Функция показывает положение значения относительно всех остальных.

library(dplyr)

df <- data.frame(
  student = c('Alice','Bob','Carol','Dave','Eve'),
  score = c(85, 92, 78, 95, 88)
)

df %>%
  mutate(
    pct_rank = round(percent_rank(score), 3),
    top_pct = round(1 - percent_rank(score), 3)
  ) %>%
  arrange(desc(score))

Оконные функции в группах

Все оконные функции начинают учитывать группы при объединении с group_by(). Для каждой группы создаётся собственное независимое окно: lag/lead не пересекают границы групп, cumsum начинается заново в каждой группе, а ранжирование выполняется внутри группы.

library(dplyr)

df <- data.frame(
  product = c('A','A','A','B','B','B'),
  month = c(1,2,3,1,2,3),
  sales = c(100, 120, 110, 200, 180, 220)
)

df %>%
  group_by(product) %>%
  mutate(
    mom_change = sales - lag(sales),
    cumulative = cumsum(sales),
    rank_in_product = row_number(sales)
  )

Объединение нескольких оконных функций

В одном вызове mutate() можно последовательно применить несколько оконных функций, чтобы создать содержательные аналитические столбцы. Это сохраняет понятность конвейера и избавляет от повторных вызовов group_by().

library(dplyr)

stock <- data.frame(
  date = as.Date(c('2024-01-01','2024-01-02','2024-01-03',
                   '2024-01-04','2024-01-05')),
  close = c(150.2, 152.8, 149.5, 155.1, 157.3)
)

stock %>%
  mutate(
    prev_close = lag(close),
    daily_return = round((close / lag(close) - 1) * 100, 2),
    running_high = cummax(close),
    distance_from_high = round(close - cummax(close), 2)
  )

lag() с аргументом default

lag(x, n=1, default=NA) принимает значение default, которым заполняются начальные позиции NA. Это полезно, когда в вычисляемых столбцах вместо пропущенных значений нужна числовая исходная точка.

library(dplyr)

df <- data.frame(
  week = 1:5,
  visitors = c(500, 620, 480, 700, 650)
)

df %>%
  mutate(
    prev_week = lag(visitors, default = 0),
    growth = visitors - lag(visitors, default = visitors[1])
  )

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

Что возвращает ntile(x, 4) для минимального значения в x?

Повторение: оконные функции

Основные выводы об оконных функциях в dplyr:

  • lag(x, n) — значение на n строк до текущей; lead(x, n) — значение на n строк после текущей
  • cumsum() — нарастающий итог; cumprod() — нарастающее произведение
  • cummax() / cummin() — нарастающий максимум / минимум
  • row_number() — целочисленный ранг внутри группы
  • ntile(x, n) — распределение по n группам (1 = наименьшие значения, n = наибольшие)
  • percent_rank(x) — дробный ранг от 0 до 1
  • Все оконные функции учитывают группы при объединении с group_by()
library(dplyr)

# Comprehensive window function example
data.frame(
  region = c('East','East','East','West','West','West'),
  month = c(1,2,3,1,2,3),
  sales = c(100, 130, 120, 200, 190, 210)
) %>%
  group_by(region) %>%
  mutate(
    mom_chg = sales - lag(sales),
    running_total = cumsum(sales),
    rank = row_number(desc(sales))
  ) %>%
  ungroup()

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

Урок «Оконные функции: lag, lead, cumsum» бесплатный?

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

Чему я научусь в уроке «Оконные функции: lag, lead, cumsum»?

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

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

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

Сколько времени занимает урок «Оконные функции: lag, lead, cumsum»?

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

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

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

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

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