R语言如何通过for循环按年份计算并存储历史波动率
原代码报错的几个直接原因
%>%管道的作用是把前一步的输出传给后一个函数的第一个参数,你直接接for循环根本跑不通,for不是可传参的函数contains()是用来匹配列名的选择器,根本不能用来筛行里的年份值,用法完全错了- 循环里你从来没定义过
data_hv_i这个对象,直接调用肯定报找不到对象 - R里取数据框行数的函数是
nrow(),没有nrows()这个函数,写了直接报错 - 你之前手动按行号切年份的方法隐患极大,只要某一年交易日数因为休市、缺数据和你记的259/260对不上,切出来的子集就会串年份,结果全错,最稳妥的方法是直接从日期列提取年份分组。
可行实现方案
前置预处理:统一日期格式
首先把字符串格式的日期转成标准日期类型,从根源避免硬编码行号的问题:
library(dplyr) library(lubridate) # 处理日期用,没装的话先跑install.packages("lubridate") # 读入数据 data_hv <- read.csv("your_file_path.csv") # 你的日期是日/月/年格式,用dmy直接转成标准日期 data_hv$date <- dmy(data_hv$date) # 新增年份列,后续分组直接用 data_hv$year <- year(data_hv$date)
方案1:for循环实现,结果输出为命名列表
完全符合你要的循环逻辑,最终结果是带年份名的列表,每年对应一个波动率值:
# 自动提取数据里所有存在的年份,不用硬写2000:2022,缺数据的年份不会空跑 year_seq <- sort(unique(data_hv$year)) # 初始化存结果的空列表 hv_list <- list() for (current_year in year_seq) { # 筛选当前年份的子集 sub_data <- data_hv[data_hv$year == current_year, ] # 取价格列,注意这里列名要和你自己数据里的对应,示例数据是prices,你之前写的Wheat要按实际改 sub_price <- sub_data$prices # 计算对数收益率:注意你之前写反了顺序,正确逻辑是当期log减上一期log,虽然标准差对称不影响波动率数值,但逻辑要对 sub_ret <- log(sub_price) - log(dplyr::lag(sub_price)) # 按你给的公式算波动率,乘当年实际交易日数的平方根 current_hv <- sd(sub_ret, na.rm = TRUE) * sqrt(nrow(sub_data)) * 100 # 结果存入列表,用年份做名字方便后续调用 hv_list[[as.character(current_year)]] <- current_hv } # 打印查看结果 print(hv_list)
方案2:不用写循环的dplyr分组实现
代码更简洁,结果可以直接转成你要的列表格式:
hv_result <- data_hv %>% group_by(year) %>% summarise( trade_days = n(), ret_list = list(log(prices) - log(dplyr::lag(prices))), annual_hv = sd(unlist(ret_list), na.rm = TRUE) * sqrt(trade_days) * 100 ) %>% select(year, annual_hv) # 转成和循环方案一样的命名列表 hv_list <- as.list(setNames(hv_result$annual_hv, hv_result$year))
补充提醒:如果你的价格列列名不是示例里的
prices,一定要把代码里对应位置改成你自己的列名,不然会报找不到对象的错。
内容的提问来源于stack exchange,提问作者user19304348
相关产品推荐
相关产品推荐

