窗口函数: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 反馈 — 无需本地设置。
此课程中的所有课时
- 分组汇总与 group_by()
- 窗口函数:lag、lead、cumsum
- dplyr 中的多表连接
- 整洁求值:{{ }} 与 .data