在R中计算两组时间序列曲线间的填充面积求助
在R语言中计算时间序列曲线填充区域的面积
问题描述
需要计算时间序列数据里,Field、Prairie两组曲线分别与min_line之间的填充区域总面积。现有数据包含日期列date_fixed、最低值列min_line,以及两组的数值列,已通过ggplot完成可视化,代码如下:
df_viz3 <- df_daily_wide %>% mutate(min_line = pmin(Field, Prairie)) %>% pivot_longer(c(Field, Prairie), names_to = "group", values_to = "y") ggplot(data = df_viz3, aes(x = date_fixed)) + geom_ribbon(aes(ymax = y, ymin = min_line, fill = group)) + labs(y = "Mean Daily Water", x = "Date") + scale_x_date(date_breaks = "1 week", date_minor_breaks = "1 week",date_labels = "%m/%d")+ scale_color_manual(values = c("aquamarine3", "slategray3")) + scale_fill_manual(values = c("aquamarine3", "slategray3")) + theme_bw() + geom_line(data = df, aes(x = date_fixed, y = rain/10), color = "skyblue2") + scale_y_continuous("Mean Daily Water Content (m3/m3)", sec.axis = sec_axis(~. * 1, name = "Rainfall (1/10 cm)"))
数据样例:
date_fixed min_line group y 5/23/2023 0.3218662 Field 0.3218662 5/23/2023 0.3218662 Prairie 0.3232029 5/24/2023 0.2842907 Field 0.3098835 5/24/2023 0.2842907 Prairie 0.2842907 5/25/2023 0.29184722 Field 0.32617778 5/25/2023 0.29184722 Prairie 0.29184722 5/26/2023 0.27190409 Field 0.30230691 5/26/2023 0.27190409 Prairie 0.27190409 5/27/2023 0.24828009 Field 0.26705671
解决方案
填充区域的面积可以通过梯形法计算,因为数据按日采样(相邻日期间隔为1天),每个区间的面积可近似为梯形面积,核心逻辑:
- 计算每个时间点的垂直高度差:
y - min_line,即填充区域在该点的高度 - 按
group分组,对每个组的高度序列,用梯形法累加所有区间的面积
具体代码实现:
library(dplyr) # 计算每个点的高度差,再按组计算总面积 df_area <- df_viz3 %>% mutate(height = y - min_line) %>% group_by(group) %>% arrange(date_fixed) %>% # 确保日期按时间顺序排列 mutate( day_diff = as.numeric(lead(date_fixed) - date_fixed), # 计算相邻日期间隔 trapezoid_area = (height + lead(height)) / 2 * day_diff # 单个梯形区间的面积 ) %>% summarise(total_area = sum(trapezoid_area, na.rm = TRUE)) # 求和得到总面积 # 输出结果 print(df_area)
关键说明
arrange(date_fixed):必须保证每个组内的日期是有序的,否则会导致面积计算错误day_diff:自动计算相邻日期的天数差,即使数据间隔不是固定1天也能适配na.rm = TRUE:最后一个数据点没有下一个对应点,lead()会返回NA,用该参数忽略不影响总和
内容的提问来源于stack exchange,提问作者pradoer
相关产品推荐
相关产品推荐

