如何在R中平滑累积数据差分后的结果?
平滑差分后累积数据的实用方法
问题背景
我有一组符合公式$x_t=x_{t-1}+x$的累积数据,要提取其中的$x$值:
- 用
diff()处理后绘图,线条太尖锐,波动过大 - 尝试
lag()函数,结果仍是累积数据,没得到预期的差分结果 - 用
geom_smooth()平滑时,过度抹平细节,与原始数据偏差太大
以下是diff()处理后的数据片段:
x y z 1 1 397.6828062 group1 2 2 482.9088128 group1 3 3 541.7299032 group1 4 4 704.2077406 group1 5 5 750.6887422 group1 6 6 768.3762029 group1 7 7 676.6482087 group1 8 8 379.2520659 group1 9 9 433.5484571 group1 10 10 364.4439592 group1 11 11 247.2131145 group1 12 12 124.6348980 group1 13 13 36.1975941 group1 14 14 0.4113363 group1 15 15 0.0000000 group1 16 16 0.0000000 group1 17 17 0.0000000 group1 18 18 0.0000000 group1 19 19 0.0000000 group1 20 20 0.0000000 group1
几种好用的平滑方案
1. 滚动窗口平均
用滑动窗口计算平均值,既能过滤小波动,又能保留整体趋势。可通过dplyr+slider或zoo包实现:
# dplyr版本 library(dplyr) library(slider) smoothed_df <- your_data %>% mutate(smoothed_y = slide_dbl(y, mean, .before = 2, .after = 2)) # 取当前点前后各2个点的平均值
或用zoo的rollmean:
library(zoo) smoothed_df <- your_data %>% mutate(smoothed_y = rollmean(y, k = 5, fill = NA)) # 窗口大小设为5,边缘用NA填充
窗口大小可灵活调整:数据波动大就调大k值,想保留更多细节就调小。
2. 自定义LOESS平滑
geom_smooth()默认的LOESS参数可能导致过度平滑,手动调小span参数即可平衡平滑度与细节:
library(ggplot2) # 先计算平滑值 loess_fit <- loess(y ~ x, data = your_data, span = 0.3) # span越小,曲线越贴近原始数据 your_data$smoothed_y <- predict(loess_fit) # 绘图对比 ggplot(your_data, aes(x, y)) + geom_line(alpha = 0.5, color = "gray") + # 原始差分曲线 geom_line(aes(y = smoothed_y), color = "red", linewidth = 1) # 平滑后曲线
span取值建议在0.2-0.5之间测试,找到适合自己数据的平衡点。
3. 样条插值平滑
样条插值能生成连续顺滑的曲线,适合有明显趋势的数据场景:
# 基础R生成平滑数据 spline_result <- spline(your_data$x, your_data$y, n = nrow(your_data)) spline_df <- data.frame(x = spline_result$x, smoothed_y = spline_result$y) # ggplot直接绘图 ggplot(your_data, aes(x, y)) + geom_point(size = 1) + geom_smooth(method = "spline", formula = y ~ x, se = FALSE, color = "blue")
这种方法生成的曲线自然流畅,不会出现滚动平均的阶梯感。
顺便修正lag()的用法
之前用lag()未得到差分结果,是写法问题,正确的差分计算应为:
your_data$diff_y <- your_data$y - lag(your_data$y, default = your_data$y[1])
这样就能得到正确的差分序列,避免后续处理出错。
内容的提问来源于stack exchange,提问作者PabloSaint
相关产品推荐
相关产品推荐

