在R中将日频DataFrame转为周频时间序列及解决decompose报错
日频转周频时间序列失败,无法使用
decompose()分解 问题描述
手上有一个日频DataFrame,想要转换为周频时间序列后用decompose()做时序分解。月度转换流程能得到规整结果,但周频转换后序列不符合预期,还无法被decompose()处理。
数据加载代码
library(tidyverse) library(quantmod) library(zoo) library(xts) adani_green_df <- read.csv("https://raw.githubusercontent.com/johnsnow09/covid19-df_stack-code/main/adani_daily_data.csv")
成功的月度转换代码及输出
adani_monthly_zoo <- adani_green_df %>% select(date,CLOSE) %>% set_names(.,c("date","Close")) %>% read.zoo(.,format = "%Y-%m-%d") %>% to.monthly() %>% Cl() %>% as.ts() adani_monthly_zoo
输出:
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2018 27.15 61.20 57.70 41.00 39.55 46.75 41.90 2019 35.70 33.05 37.25 40.25 43.10 44.45 46.75 46.20 58.25 89.65 137.20 166.50 2020 189.45 154.90 153.65 210.25 247.85 358.70 340.65 453.60 737.85 856.25 1120.80 1052.55 2021 1003.75 1168.05 1104.30 1019.00 1267.25 1116.90 888.20 1066.85 1147.25 1146.35 1291.20 1327.75 2022 1878.75 1839.10 1913.40 2887.30 1898.80 1929.00 2168.45 2436.70 2347.00
失败的周频转换代码及输出
adani_weekly_zoo <- adani_green_df %>% select(date,CLOSE) %>% set_names(.,c("date","Close")) %>% read.zoo(.,format = "%Y-%m-%d") %>% to.weekly() %>% Cl() %>% as.ts() adani_weekly_zoo
输出:
Time Series: Start = 17704 End = 19254 Frequency = 1 [1] 29.45 NA NA NA NA NA NA 27.15 NA NA NA NA [13] NA NA 30.05 NA NA NA NA NA NA 31.50 NA NA [25] NA NA NA NA 35.30 NA NA NA NA NA NA 53.00 [37] NA NA NA NA NA NA 70.80 NA NA NA NA NA [49] NA 66.90 NA NA NA NA NA NA 55.05 NA NA NA
decompose()测试结果
- 月度序列可正常运行:
adani_monthly_zoo %>% decompose() %>% plot()
- 周频序列运行失败:
adani_weekly_zoo %>% decompose() %>% plot()
报错信息:
Error in decompose(.) : time series has no or less than 2 periods
解决方案
问题核心是原流程生成的周频序列本质是日频时间序列(frequency=1),中间填充了大量NA,导致decompose()无法识别有效周期。需要先按周聚合得到每周一个值的序列,再指定正确的周频周期(一年52周)。
方法1:用zoo的aggregate按周聚合
# 按周聚合,取每周最后一个交易日的收盘价 adani_weekly_zoo <- adani_green_df %>% select(date, CLOSE) %>% set_names(c("date", "Close")) %>% mutate(date = as.Date(date)) %>% read.zoo(index = "date") %>% aggregate(as.yearmon(index(.), "%Y-%W"), tail, 1) # 转为ts对象并指定频率为52(一年52周) adani_weekly_ts <- as.ts(adani_weekly_zoo, frequency = 52) # 正常执行分解 decompose(adani_weekly_ts) %>% plot()
方法2:用xts的apply.weekly处理
# 生成xts对象并按周提取收盘价 adani_weekly_xts <- adani_green_df %>% select(date, CLOSE) %>% set_names(c("date", "Close")) %>% mutate(date = as.Date(date)) %>% xts(x = .$Close, order.by = .$date) %>% apply.weekly(Cl) # 转为ts对象并指定频率52 adani_weekly_ts <- as.ts(adani_weekly_xts, frequency = 52) # 正常执行分解 decompose(adani_weekly_ts) %>% plot()
内容的提问来源于stack exchange,提问作者ViSa
相关产品推荐
相关产品推荐

