在R中将周度数据转换为时间序列以进行预测
Got it, let's work through this problem together. Your dataset has quarters, weeks within each quarter, and values for variables A and B, but no actual dates—we'll turn this into a proper 52-week frequency time series that's ready for forecasting.
First, let's start with your original data (formatted as an R code block):
df <- structure( list( Variable = c("A", "B", "A", "B", "A", "B", "A", "B", "A"), Quantity = c("1", "100", "2", "5", "6", "30", "8", "15", "133"), YearQuarter = c("2017Q2", "2017Q2", "2017Q3", "2017Q3", "2017Q4", "2017Q4", "2018Q1", "2018Q1", "2018Q2"), Week = c("1", "10", "1", "2", "1", "6", "2", "9", "13") ), class = "data.frame", row.names = c(NA, -9L) )
Step 1: Clean and Transform the Data
First, we need to fix data types (Quantity is currently character) and calculate the yearly week number (since each quarter maps to 13 weeks: Q1=1-13, Q2=14-26, Q3=27-39, Q4=40-52). We'll use dplyr and lubridate for this:
library(dplyr) library(lubridate) # Clean data types and extract year/quarter df_clean <- df %>% mutate( Quantity = as.numeric(Quantity), Week = as.integer(Week), # Extract year and quarter number from YearQuarter string Year = as.integer(substr(YearQuarter, 1, 4)), Quarter = as.integer(substr(YearQuarter, 5, 5)) ) %>% # Calculate the position of the week within the full year mutate(YearlyWeek = Week + (Quarter - 1)*13) %>% select(Variable, Year, YearlyWeek, Quantity)
Step 2: Create a Complete 52-Week Time Frame
Your data has gaps (not every week has observations for A or B), so we'll create a full grid of all years and 52 weeks, then merge your data into it. This ensures our time series is continuous:
# Get all unique years from your dataset years <- unique(df_clean$Year) # Create a full grid of variables, years, and all 52 weeks full_time_grid <- expand.grid( Variable = c("A", "B"), Year = years, YearlyWeek = 1:52 ) # Merge with cleaned data, fill missing values (adjust NA handling based on your use case) ts_data <- full_time_grid %>% left_join(df_clean, by = c("Variable", "Year", "YearlyWeek")) %>% # Optional: Replace NAs with 0, or use interpolation later if needed mutate(Quantity = tidyr::replace_na(Quantity, 0))
Step 3: Convert to a Time Series Object
For forecasting, you can use either base R's ts object or a more modern tidy format like tsibble (ideal for the fable forecasting package).
Option 1: Base R ts Object (split by Variable)
Since we have two variables, we'll create separate time series for A and B:
# Create time series for Variable A ts_A <- ts_data %>% filter(Variable == "A") %>% pull(Quantity) %>% ts(start = c(min(years), 1), frequency = 52) # Create time series for Variable B ts_B <- ts_data %>% filter(Variable == "B") %>% pull(Quantity) %>% ts(start = c(min(years), 1), frequency = 52) # Check the structure of the time series ts_A
Option 2: tsibble for Tidy Forecasting
If you prefer a tidy approach (recommended for flexible forecasting), use the tsibble package:
library(tsibble) # Create a tsibble with a year-week index tsibble_data <- ts_data %>% # Combine Year and YearlyWeek into a standard year-week index mutate(WeekIndex = yearweek(paste(Year, YearlyWeek, sep = "-W"))) %>% select(Variable, WeekIndex, Quantity) %>% as_tsibble(key = Variable, index = WeekIndex) # View the tidy time series tsibble_data
Step 4: Forecast Future Weeks
With your time series ready, you can use packages like forecast (for base R ts objects) or fable (for tsibble). Here's an example using fable to forecast the next 52 weeks:
library(fable) library(feasts) # Fit an ARIMA model and forecast 52 weeks ahead forecast_result <- tsibble_data %>% model(ARIMA(Quantity)) %>% forecast(h = 52) # Plot the forecast alongside historical data forecast_result %>% autoplot(tsibble_data)
This setup gives you a continuous 52-week frequency time series, perfect for forecasting future weeks. Adjust the missing value handling (e.g., use linear interpolation instead of 0) based on your specific data context!
内容的提问来源于stack exchange,提问作者flightless13wings

