如何在R中基于单条记录绘制运行累计总和?附数据集处理需求
在R中基于单个记录绘制运行累计总和的方法
没问题,我来帮你一步步搞定这个需求!你的数据集记录了不同城市的项目参与时间段和人口数,我们需要把这些单个记录转化为时间事件序列,再计算累计参与人数,最后绘制运行总和图。
步骤1:数据预处理(转换日期格式)
首先,你给的日期是字符型,R没法正确识别时间顺序,所以第一步要把Enter.Program和Leave.Program转换成日期类型:
# 加载需要的包(没安装的话先运行:install.packages(c("dplyr", "tidyr", "ggplot2"))) library(dplyr) library(tidyr) library(ggplot2) # 你的原始数据 example.dat <- data.frame( Population = c(1000, 2000, 3000), Enter.Program = c("15-10-01", "16-05-01", "16-07-01"), Leave.Program = c("16-06-01", "16-10-01", "17-08-01") ) # 转换日期格式:注意你的日期是日-月-年,所以用"%d-%m-%y" example.dat <- example.dat %>% mutate( Enter.Program = as.Date(Enter.Program, format = "%d-%m-%y"), Leave.Program = as.Date(Leave.Program, format = "%d-%m-%y") )
步骤2:生成事件序列数据框
我们需要把每个城市的记录拆成两个事件:进入项目(人口增加)和离开项目(人口减少)。用pivot_longer可以快速完成这个转换:
event_data <- example.dat %>% pivot_longer( cols = c(Enter.Program, Leave.Program), names_to = "Event_Type", values_to = "Event_Date" ) %>% # 给事件对应的人口变化赋值:进入是+Population,离开是-Population mutate(Pop_Change = ifelse(Event_Type == "Enter.Program", Population, -Population)) %>% # 只保留需要的列 select(Event_Date, Pop_Change)
转换后的event_data示例:
Event_Date Pop_Change 1 2015-10-01 1000 2 2016-06-01 -1000 3 2016-05-01 2000 4 2016-10-01 -2000 5 2016-07-01 3000 6 2017-08-01 -3000
步骤3:计算运行累计总和
接下来按时间排序事件,然后用cumsum()计算累计参与人数:
cumulative_data <- event_data %>% arrange(Event_Date) %>% mutate(Cumulative_Pop = cumsum(Pop_Change))
得到的累计数据示例:
Event_Date Pop_Change Cumulative_Pop 1 2015-10-01 1000 1000 2 2016-05-01 2000 3000 3 2016-06-01 -1000 2000 4 2016-07-01 3000 5000 5 2016-10-01 -2000 3000 6 2017-08-01 -3000 0
步骤4:绘制运行累计总和图
用ggplot2绘制折线图,能清晰展示人数随时间的变化:
ggplot(cumulative_data, aes(x = Event_Date, y = Cumulative_Pop)) + geom_line(color = "#2c3e50", size = 1.2) + geom_point(size = 3, color = "#e74c3c") + labs( title = "项目参与人数累计变化", x = "日期", y = "累计参与人数" ) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))
这个图会显示每个事件点的人数突变,折线连接后就是完整的运行累计趋势。
额外提示
- 如果你的数据集包含多个城市,只需要在
pivot_longer前保留City列,绘图时加上facet_wrap(~City)就能分城市展示各自的趋势。 - 要是需要更精细的时间粒度(比如按月份统计),可以用
lubridate::floor_date()把日期统一到月/周级别后再计算累计值。
内容的提问来源于stack exchange,提问作者bikeclub
相关产品推荐
相关产品推荐

