You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中对时间-计数阶梯图做非均匀分箱:聚合计数变化<10的区间

解决时间-计数阶梯图的连续小变化区间聚合问题

要实现将相邻计数变化小于10的连续区间聚合,确保最终保留的序列中任意相邻点的计数变化绝对值都≥10,可通过以下两种方法实现:

方法一:Base R 循环实现

逻辑直观,逐个遍历数据点,仅保留与上一个保留点计数变化≥10的节点,同时确保末尾点不丢失。

set.seed(123) # 保证可复现
time <- c(0,sort(sample.int(365,50)))
counts <- c(1000,sort(sample.int(1000,50), decreasing = TRUE))

# 初始化保留索引,第一个点必保留
keep_idx <- 1L
last_keep_count <- counts[1]

# 遍历后续数据点
for (i in 2:length(counts)) {
  current_count <- counts[i]
  # 若当前点与上一个保留点的变化≥10,则保留
  if (abs(current_count - last_keep_count) >= 10) {
    keep_idx <- c(keep_idx, i)
    last_keep_count <- current_count
  }
}

# 确保最后一个点被保留(处理末尾连续小变化场景)
if (tail(keep_idx, 1) != length(counts)) {
  keep_idx <- c(keep_idx, length(counts))
}

# 提取聚合后的数据
df_agg <- data.frame(time = time[keep_idx], counts = counts[keep_idx])

# 绘制聚合后的阶梯图
plot(x = df_agg$time, y = df_agg$counts, type = "S", main = "聚合后的时间-计数阶梯图")

方法二:dplyr 分组聚合实现

利用dplyr的分组功能,将连续小变化的点归为同一组,每组仅保留首尾端点,自动过滤中间冗余点。

library(dplyr)

set.seed(123)
time <- c(0,sort(sample.int(365,50)))
counts <- c(1000,sort(sample.int(1000,50), decreasing = TRUE))

df <- data.frame(time = time, counts = counts)

df_agg <- df %>%
  # 计算与前一个点的计数差值绝对值
  mutate(diff_prev = abs(counts - lag(counts, default = first(counts)))) %>%
  # 标记需保留的点:第一个点,或与前一个点变化≥10的点
  mutate(to_keep = row_number() == 1 | diff_prev >= 10) %>%
  # 按连续非保留点分组(遇到保留点时开启新组)
  mutate(group = cumsum(to_keep)) %>%
  # 每组保留首尾两个点
  group_by(group) %>%
  slice(c(1, n())) %>%
  ungroup() %>%
  # 去重(避免单元素组的重复行)
  distinct(time, counts, .keep_all = TRUE) %>%
  select(time, counts)

# 绘制聚合后的阶梯图
plot(x = df_agg$time, y = df_agg$counts, type = "S", main = "dplyr聚合后的时间-计数阶梯图")

特殊场景测试

针对你提到的counts = c(57,55,49)这类连续小变化序列,两种方法都会保留首尾点;若后续出现与末尾点变化≥10的节点,会自动保留该节点,确保所有相邻变化符合要求。示例测试:

test_time <- c(1,2,3,4)
test_counts <- c(57,55,49,38)

# 方法一处理
keep_idx <- 1L
last_keep_count <- test_counts[1]
for (i in 2:length(test_counts)) {
  current_count <- test_counts[i]
  if (abs(current_count - last_keep_count) >=10) {
    keep_idx <- c(keep_idx, i)
    last_keep_count <- current_count
  }
}
if (tail(keep_idx,1) != length(test_counts)) keep_idx <- c(keep_idx, length(test_counts))

test_agg <- data.frame(time=test_time[keep_idx], counts=test_counts[keep_idx])
# 结果保留(1,57)和(4,38),变化绝对值19≥10,符合要求

内容的提问来源于stack exchange,提问作者Sarah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:35:02