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

R语言中按分组筛选连续符合阈值的首周数据

解决方案:按地点和年份筛选符合条件的周(去重连续项)

嘿,我来帮你搞定这个筛选需求!这里用两种方法实现——dplyr(简洁直观)和Base R(无需额外包),都能精准满足你的要求:按地点+年份分组,找出cumsum.val>1的周,连续两周满足的只留第一周。

先确认数据生成代码

先把你提供的数据生成代码放出来,确保我们用的是同一组测试数据:

set.seed(123)
df <- data.frame(
  loc.id = rep(1:3, each = 3*5),
  year = rep(rep(1981:1983, each = 5), times = 3),
  week = rep(rep(20:24, times = 3), times = 3),
  cumsum.val = runif(min = -2, max = 4, n = 5*3*3)
)

方法1:用dplyr包(推荐,代码清晰易读)

如果你已经安装了dplyr,直接用下面的代码就能搞定:

library(dplyr)

filtered_df <- df %>%
  # 按地点和年份分组,确保每组独立处理不干扰
  group_by(loc.id, year) %>%
  # 先筛掉cumsum.val≤1的行,只保留符合数值要求的周
  filter(cumsum.val > 1) %>%
  # 标记当前周是否和上一个符合条件的周连续(周数差为1)
  mutate(
    is_consecutive = week == lag(week) + 1
  ) %>%
  # 保留组内第一行(无前置行,is_consecutive为NA),以及非连续的行——也就是连续段的起始周
  filter(is.na(is_consecutive) | !is_consecutive) %>%
  # 删除辅助标记列,让结果更干净
  select(-is_consecutive) %>%
  # 取消分组,回到普通数据框格式
  ungroup()

代码细节解释

  • group_by(loc.id, year):把数据拆分成每个地点+年份的独立小组,避免跨组处理导致的错误。
  • filter(cumsum.val > 1):先砍掉不符合数值条件的行,减少后续计算量。
  • mutate(...):用lag(week)获取上一行的周数,判断当前周是否是连续的下一周。组内第一行没有上一行,所以is_consecutive会返回NA。
  • filter(...):自动过滤掉连续两周中的第二周,只保留连续段的起始周和孤立符合条件的周。

方法2:Base R实现(无需额外安装包)

如果不想依赖dplyr,用Base R原生代码也能实现相同效果:

# 按地点和年份拆分数据成子数据框列表
split_df <- split(df, list(df$loc.id, df$year), drop = TRUE)

# 遍历每个子数据框进行筛选处理
filtered_list <- lapply(split_df, function(sub_df) {
  # 先筛出cumsum.val>1的行
  sub_filtered <- sub_df[sub_df$cumsum.val > 1, ]
  # 如果当前组没有符合条件的行,直接返回空数据框
  if (nrow(sub_filtered) == 0) return(sub_filtered)
  
  # 计算周数差值,判断是否连续(diff返回后项减前项,差为1则连续)
  consecutive <- c(FALSE, diff(sub_filtered$week) == 1)
  # 保留非连续的行(即连续段的第一行)
  sub_filtered[!consecutive, ]
})

# 合并所有处理后的子数据框,重置行名让结果整洁
filtered_df_base <- do.call(rbind, filtered_list)
rownames(filtered_df_base) <- NULL

代码细节解释

  • split(...):把原数据拆分成多个子数据框,每个子框对应一个地点+年份的组合。
  • lapply(...):遍历每个子框,先筛选符合数值条件的行,再用diff(week)计算周数差,标记连续行后只保留非连续的行。
  • do.call(rbind, ...):把处理好的子框合并成一个完整的数据框,重置行名避免混乱。

验证结果

你可以查看某个特定组的筛选结果,比如loc.id=1,year=1981:

# 查看dplyr方法的结果
filtered_df %>% filter(loc.id == 1, year == 1981)

# 查看Base R方法的结果
filtered_df_base %>% filter(loc.id == 1, year == 1981)

两种方法得到的结果完全一致,都能精准满足你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:22:33