R中如何对单个dataframe及列表应用函数计算滚动3月收益率
报错原因
你之前lapply调用失败有两个核心问题:
lapply(stefi$return, calc_3m_return)会把return列的每一个单独数值传给函数,而lag需要作用在完整的收益率序列上才能取到前2期的值,单个数值根本无法完成滚动计算- 你在
lapply末尾多传了多余的return参数,你的自定义函数没有定义这个入参,自然会报“unused argument”错误
单个DataFrame的apply类方法实现
滚动窗口计算场景更适合用zoo包的rollapply(属于apply类函数族),专门处理这类需求,写法如下:
# 加载所需包 library(dplyr) library(zoo) # 滚动3月收益率计算函数 calc_3m_return <- function(return_vec) { prod(return_vec + 1) - 1 } # 单个dataframe计算:窗口设为3,对齐到窗口末尾,不足窗口的位置返回NA stefi <- stefi %>% mutate(return_3m = rollapply(return, width = 3, FUN = calc_3m_return, align = "right", fill = NA))
运行结果和你当前用lag实现的效果完全一致。
DataFrame列表的批量计算方案
假设你存储多个组合/基准数据的列表为port_list,每个列表元素都是和stefi结构相同的DataFrame,直接用lapply遍历整个列表即可完成批量计算:
# 示例构造DataFrame列表:这里复制3份stefi模拟3个不同组合的数据 port_list <- list(stefi, stefi, stefi) # 批量计算每个组合的滚动3月收益率 port_list_calc <- lapply(port_list, function(df) { df %>% mutate(return_3m = rollapply(return, width = 3, FUN = calc_3m_return, align = "right", fill = NA)) })
运行后得到的port_list_calc就是计算完成的列表,每个元素都新增了return_3m列。
如果你不想额外安装zoo包,用你原来基于lag的函数也可以,批量处理逻辑完全一致:
# 基于lag的计算函数 calc_3m_return_lag <- function(return_vec){ (return_vec + 1) * (lag(return_vec, 1) + 1) * (lag(return_vec, 2) + 1) - 1 } # 批量处理 port_list_calc <- lapply(port_list, function(df) { df %>% mutate(return_3m = calc_3m_return_lag(return)) })
内容的提问来源于stack exchange,提问作者Bandit King
相关产品推荐
相关产品推荐

