在R中基于时序数据生成以时长为纵轴的直方图
嘿,我完全懂你的问题——普通的hist(z, freq=T)只会数每个区间里有多少个数据点,但完全没考虑你的数据是采样保持模式的不规则时序,每个数据点其实对应一段持续时间对吧?这就导致普通直方图完全不符合你的需求。别担心,我给你一套具体的解决方案,一步步来:
步骤1:拆解zoo数据,计算每个数据点的持续时长
首先我们得把zoo对象里的时间戳和数值拆出来,然后算出每个数值状态持续了多久——毕竟相邻时间戳之间,数据是保持恒定的。
library(zoo) # 假设你的zoo对象名为z,先转换成数据框方便操作 df <- data.frame( timestamp = index(z), # 提取时间戳索引 value = coredata(z) # 提取对应的数值 ) # 计算每个数据点的持续时长:下一个时间戳 - 当前时间戳 # 最后一个数据点的时长可以设为0,或者根据你的观测结束时间手动调整 df$duration <- c(diff(df$timestamp), 0)
步骤2:划分数值区间,汇总每个区间的总时长
接下来我们需要把数值分成你想要的直方图区间,然后把每个区间内所有数据点的持续时长加起来——这才是你真正需要的"区间总时长"。
# 自定义区间:比如从数值最小值到最大值,分成10个等距区间 # 你也可以手动指定breaks,比如breaks = c(0, 10, 20, 30, 40, 50) breaks <- seq(min(df$value), max(df$value), length.out = 11) # 11个断点对应10个区间 # 把每个数值分配到对应的区间里 df$interval <- cut(df$value, breaks = breaks, include.lowest = TRUE) # 按区间分组,汇总总时长 duration_summary <- aggregate(duration ~ interval, data = df, sum)
步骤3:绘制基于总时长的"直方图"
因为普通的hist()函数没法直接处理这种基于时长的统计,我们用barplot()来实现——本质上这就是你要的"时长直方图":
# 绘制条形图,x轴是数值区间,y轴是总时长 barplot( height = duration_summary$duration, names.arg = duration_summary$interval, xlab = "数值区间", ylab = "总时长", main = "基于持续时长的数值直方图", col = "#2596be", cex.names = 0.7 # 如果区间标签太长,调小字号避免重叠 )
一些额外的小提示
- 如果你的时间戳是POSIXct/POSIXlt类型,
diff()返回的是秒数,你可以用difftime()转换成更友好的单位,比如小时:df$duration <- c(difftime(lead(df$timestamp), df$timestamp, units = "hours"), 0) - 最后一个数据点的时长如果需要对应到观测结束的时间,不要直接设为0,手动替换成
as.difftime(your_end_time - last_timestamp, units = "hours") - 可以用
pretty(df$value)自动生成更美观的区间断点,替代手动的seq()
内容的提问来源于stack exchange,提问作者Jendem
相关产品推荐
相关产品推荐

