R中decompose分解时间序列后趋势项出现NA值的原因及解决方法
decompose() & How to Fix It What's Causing the NA Values?
The decompose() function in R relies on centered moving averages to estimate the trend component of your time series. Since you’re working with weekly data (frequency = 52), it uses a 52-period centered moving average to capture the long-term trend.
For an even-length moving average like 52, each trend value requires 26 observations before and after the current point to compute the average. At the very start of your series (first 26 weeks) and the very end (last 26 weeks), there aren’t enough adjacent data points to calculate this average—so those positions get marked as NA.
Since the random component is calculated as original series - trend - seasonal, any position with an NA trend will also result in an NA random value.
How to Get Complete Trend Data
Here are two practical solutions to resolve this issue:
1. Switch to stl() (Recommended)
The stl() function (Short-Term Long-Term decomposition) uses LOESS smoothing instead of moving averages, and it naturally handles the start/end of the series without producing NA values. It’s more robust for seasonal time series overall.
Try this code:
# Create your time series (same as your original code) myts <- c(5,40,43,65,95,111,104,124,133,263,388,1488,796,1209,707,52,0,76,306,1219,671,318,125,192,128,33,5,17,54,55,74,133,111,336,321,34,74,210,280,342,708,232,479,822,188,104,50,24,3,1,0,0,8,55,83,75,104,163,169,259,420,1570,243,378,1036,834,856,17,8,88,359,590,768,1461,443,128,89,192,37,21,51,62,78,125,123,259,600,60,59,180,253,379,766,375,828,502,165,114,76,10,2,1,0,0,46,71,95,102,132,212,268,330,428,1635,302,461,993,1497,1137,29,2,219,436,817,979,1226,317,134,121,211,35,47,87,83,97,177,153,345,635,48,84,234,258,358,780,470,700,701,331,67,0,0,0,0,0,0) myts <- ts(myts, start=c(2015,17), frequency = 52) # Decompose with stl modelo_stl <- stl(myts, s.window = "periodic") plot(modelo_stl) # Extract the complete trend component trend_complete <- modelo_stl$time.series[, "trend"]
The s.window = "periodic" argument ensures the seasonal component stays consistent across each week of the year, which is perfect for weekly seasonal data.
2. Manually Fill NA Values (If You Prefer decompose())
If you want to stick with decompose(), you can fill the NA gaps in the trend component using interpolation or forward/backward filling. The zoo package simplifies this process:
# Install and load the zoo package if you haven't already # install.packages("zoo") library(zoo) # Your original decomposition model modelo1 <- decompose(myts, "additive") # Option 1: Fill NAs with linear interpolation (smooth and accurate) trend_filled <- na.approx(modelo1$trend) # Option 2: Forward-fill start NAs, then backward-fill end NAs (simpler) # trend_filled <- na.locf(modelo1$trend, fromLast = FALSE) # Forward fill start # trend_filled <- na.locf(trend_filled, fromLast = TRUE) # Backward fill end # Calculate the filled random component random_filled <- myts - trend_filled - modelo1$seasonal
na.approx()uses linear interpolation to create smooth transitions across NA gaps, which is a good balance between simplicity and accuracy.na.locf()carries the last observed value forward/backward—easy to implement, but may introduce bias if the trend shifts sharply near the edges of your series.
Quick Notes
stl()will produce slightly different trend values thandecompose()because it uses LOESS instead of moving averages, but it’s generally more reliable for real-world seasonal data.- Always visualize the filled trend component to ensure the interpolation/filling makes sense for your specific dataset.
内容的提问来源于stack exchange,提问作者Francesc Pons Álvarez

