R语言时间序列合并报错:'start'不能晚于'end'问题排查
Let's dig into why you're hitting these errors and fix them up step by step. You mentioned setting data.start and data.end to the earliest and latest dates across your series, but still getting a 'start' cannot be after 'end' error plus warnings about mismatched row lengths—here's what's going on:
Root Cause: Mixed Time Series Types (ts vs tis)
The biggest issue is that you're mixing base R ts objects (like your gdp.ger series) with tis package objects (like inflation.seasadj.ger and interest.ger). When you run cbind() on a mix of these two types, R converts them to plain numeric vectors—losing all critical time series metadata. Without that metadata, the window() function can't interpret your data.start and data.end correctly, leading to the confusing "start after end" error.
The row-length warning also stems from this mixing: plain vectors don't respect time alignment, so R just sticks values together or recycles them, creating mismatched lengths.
Step-by-Step Fixes
1. Standardize on One Time Series Type
Let's stick with base R's ts objects for consistency (since you start with them, and they play nicely with window()). Here's how to adjust your code:
Fix the Inflation Section
Your current inflation code has an undefined variable (cpi) and switches to tis unnecessarily. Rewrite it to use ts throughout:
# Import raw data: inflation inflation.start <- c(1960,1) inflation.end <- c(2018,1) inflation.raw <- "rawData/germany_inflation.csv" inflation.table <- read.table(inflation.raw, skip = 1, header = F, sep = ',', stringsAsFactors = F) inflation.ger <- ts(inflation.table[,2], start = inflation.start, frequency = 4) # Seasonal adjustment (keep as ts object) inflation.seasadj.ger <- final(seas(inflation.ger)) # seas() works directly on ts objects # Calculate inflation expectations (4-quarter moving average) # Use base R's lag() instead of tis's Lag() inflation.exp.ger <- (inflation.seasadj.ger + lag(inflation.seasadj.ger, k=1) + lag(inflation.seasadj.ger, k=2) + lag(inflation.seasadj.ger, k=3))/4
Fix the Interest Rate Section
Convert the interest rate series to ts instead of tis to match the rest:
# Import raw data: short-term nominal interest rate interest.start <- c(1960,2) interest.end <- c(2018,2) interest.raw <- 'rawData/germany_interest.csv' interest.table <- read.table(interest.raw, skip = 1, header = F, sep = ',', stringsAsFactors = F) interest.m <- ts(interest.table[,2], start = interest.start, frequency = 12) # monthly ts # Convert monthly to quarterly (base R alternative to convert()) interest_q <- aggregate(interest.m, nfrequency = 4, FUN = mean) # average monthly values to quarterly # Seasonal adjustment (keep as ts) interest.seasadj <- final(seas(interest_q)) # Annualize the rate (keep as ts) interest.ger <- 100*((1+interest.seasadj/36000)^365 -1)
Fix the GDP Section
Finish the log transformation (this part already uses ts, so just wrap up):
# Prepare Data: Take log of real GDP gdp.log.ger <- log(gdp.ger)
2. Align All Series to Your Target Date Range
Now that all series are ts objects, use window() on each one individually first to align them to your desired start/end dates, then combine them:
# Define your target date range data.start <- c(1960,1) data.end <- c(2018,2) # Window each series to the target range (fills gaps with NA where data is missing) gdp_windowed <- window(gdp.log.ger, start = data.start, end = data.end) interest_windowed <- window(interest.ger, start = data.start, end = data.end) inflation_windowed <- window(inflation.seasadj.ger, start = data.start, end = data.end) inflation_exp_windowed <- window(inflation.exp.ger, start = data.start, end = data.end) # Combine into a single ts object data.out <- cbind(gdp_windowed, interest_windowed, inflation_windowed, inflation_exp_windowed) colnames(data.out) <- c("gdp.log","interest","inflation","inflation.expectations") # Export to CSV write.table(data.out,file = 'InputData/rstar.data.ge.csv', sep = ',', col.names = TRUE, quote = FALSE, na = '.', row.names = FALSE)
Why This Works
- By keeping all time series as
tsobjects, R preserves their date metadata, sowindow()can correctly slice each series to your desired range. - Aligning each series individually before combining ensures they all have the same number of observations (with
NAs filling in gaps where a series doesn't have data for a date). - No more mixing types means no more unexpected vector conversion or row-length mismatches.
内容的提问来源于stack exchange,提问作者Sean

