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

在R中保留数值符号变化前后指定数量的观测值

解决流量数据符号变化前后的筛选问题

核心思路

要满足你的筛选条件,关键是识别连续同符号的分段,然后找到符合「前一段≥3个同符号、后一段≥3个同符号且符号相反」的分段组合,最后提取这些分段对应的原始观测值。这里用rle()(游程编码)处理连续符号段是最高效的方式,再结合dplyr完成数据筛选与匹配。

代码实现

基于你的示例数据演示完整流程:

library(dplyr)

# 示例数据
wf = data.frame(discharge = c(100, 125, 128, -25, -30, -27, 104, -23, 100, -50))

# 1. 生成符号列和连续符号段标识
wf <- wf %>%
  mutate(
    sign_d = sign(discharge),
    # 为每个观测分配所属的连续符号段ID
    run_id = with(rle(sign_d), rep(seq_along(values), lengths))
  )

# 2. 统计每个符号段的关键信息
run_summary <- wf %>%
  group_by(run_id) %>%
  summarize(
    run_length = n(),
    run_sign = first(sign_d),
    start_row = min(row_number()),
    end_row = max(row_number())
  ) %>%
  ungroup()

# 3. 筛选符合条件的分段对
valid_pairs <- run_summary %>%
  mutate(
    prev_length = lag(run_length),
    prev_sign = lag(run_sign)
  ) %>%
  filter(
    run_length >= 3,
    prev_length >= 3,
    run_sign != prev_sign
  )

# 4. 提取目标观测值
valid_rows <- c(
  # 提取符合条件的前一段所有行
  unlist(lapply(valid_pairs$run_id - 1, function(x) run_summary$start_row[x]:run_summary$end_row[x])),
  # 提取符合条件的后一段所有行
  unlist(lapply(valid_pairs$run_id, function(x) run_summary$start_row[x]:run_summary$end_row[x]))
)

# 最终结果
result <- wf$discharge[sort(valid_rows)]
print(result)
# [1] 100 125 128 -25 -30 -27

代码解释

  1. 符号与分段标识:用sign()获取流量正负符号,通过rle()生成连续符号段的ID,让每个观测值对应到所属的连续符号组。
  2. 分段统计:对每个符号段统计长度、符号、起止行号,为后续条件判断提供基础数据。
  3. 筛选有效分段对:用lag()调用前一个分段的信息,筛选出满足「前后段长度≥3、符号相反」的分段组合。
  4. 提取目标观测:根据有效分段的起止行号,提取对应的原始流量值,排序后得到最终结果。

适配5分钟间隔数据

针对你每小时12条的5分钟间隔数据,这段代码可直接复用——只需将wf替换为你的实际数据框,指定对应流量列即可。如果需要调整前后连续值的数量(比如对应N小时的12*N条),仅需修改filter()中run_length >= 3和prev_length >= 3的数字。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:00:24