如何基于DataFrame列动态设置lag函数n值计算价格变动率
解决方法
核心思路
因为lag()函数的n参数仅支持单个整数,无法直接传入向量列,所以需要按分组逐行通过索引定位回溯价格,而非依赖lag()函数。以下是三种可行方案:
方案1:dplyr + purrr(适配tidyverse工作流)
先按ticker分组,逐个处理每个分组的子数据集,通过遍历行号定位对应回溯价格:
library(dplyr) library(purrr) # 先确保数据按ticker和时间排序(关键步骤!) df <- df %>% arrange(ticker, date) df <- df %>% group_by(ticker) %>% group_map(~{ .x %>% mutate(variation = map_dbl(row_number(), ~{ # 获取当前行的回溯天数 n_days <- .x$daysPrevWeek[.y] # 行号大于回溯天数时计算变动率,否则返回NA if (.y > n_days) { (.x$price[.y] / .x$price[.y - n_days]) - 1 } else { NA_real_ } })) }, .keep = TRUE) %>% bind_rows()
方案2:dplyr rowwise(简洁版)
先给每个分组内的行编号,再逐行通过索引计算,规避lag()的参数限制:
library(dplyr) # 先排序 df <- df %>% arrange(ticker, date) df <- df %>% group_by(ticker) %>% mutate(row_num = row_number()) %>% # 分组内生成连续行号 rowwise() %>% mutate(variation = ifelse(row_num > daysPrevWeek, (price / price[row_num - daysPrevWeek]) - 1, NA_real_)) %>% ungroup() %>% select(-row_num) # 移除辅助行号列
方案3:data.table(高效处理大数据)
如果数据集规模较大,data.table的分组计算性能更优:
library(data.table) # 转成data.table并按ticker和时间排序 setDT(df) df <- df[order(ticker, date)] # 分组生成行号并计算变动率 df[, row_num := .I, by = ticker] df[, variation := ifelse(row_num > daysPrevWeek, (price / price[row_num - daysPrevWeek]) - 1, NA_real_), by = ticker]
注意事项
- 必须先按
ticker和时间列(比如date)排序,否则回溯的价格会对应错误的时间点。 - 当分组内当前行的行号小于等于
daysPrevWeek时,前面没有足够的历史数据,返回NA是合理结果。
内容的提问来源于stack exchange,提问作者Juan M
相关产品推荐
相关产品推荐

