0Pricing
R Academy · 课时

窗口函数:lag、lead、cumsum

在各组内计算运行总计、偏移量和累计聚合值

窗口函数:lag、lead、cumsum 是 CoddyKit 上的免费 R Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 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)
  )

带 default 参数的 lag()

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])
  )

快速检查

对于 x 中的最小值,ntile(x, 4) 会返回什么?

回顾:窗口函数

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」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「窗口函数:lag、lead、cumsum」这节课中我会学到什么?

在各组内计算运行总计、偏移量和累计聚合值 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 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