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

如何在R中按条件筛选每周从首次降雨至周末的时段?

问题

我开展了多次为期约一周的实验,希望保留每周中从首次出现precipitation(降雨)开始至周末的行/时段。已掌握如何剔除完全无雨的周,但不清楚如何筛选有雨周中从首次降雨到周末的时段。

数据规则说明:

  • 在week 15中,仅需保留第144至150行,其余行剔除;
  • 完全无雨的week 16需整周剔除。

注意:允许周内存在多次干湿交替时段,核心是忽略每周首次降雨前的无雨时段。

可复现代码:

df <- structure(
  list(
    week = structure(
      c(
        1L,1L,1L,1L,1L,1L,1L,1L,1L,1L,
        2L,2L,2L,2L,2L,2L,2L,2L,2L,2L,
        3L,3L,3L,3L,3L,3L,3L,3L,3L,3L,
        4L,4L,4L,4L,4L,4L,4L,4L,4L,4L,
        5L,5L,5L,5L,5L,5L,5L,5L,5L,5L,
        6L,6L,6L,6L,6L,6L,6L,6L,6L,6L,
        7L,7L,7L,7L,7L,7L,7L,7L,7L,7L,
        8L,8L,8L,8L,8L,8L,8L,8L,8L,8L,
        9L,9L,9L,9L,9L,9L,9L,9L,9L,9L,
        10L,10L,10L,10L,10L,10L,10L,10L,10L,10L,
        11L,11L,11L,11L,11L,11L,11L,11L,11L,11L,
        12L,12L,12L,12L,12L,12L,12L,12L,12L,12L,
        13L,13L,13L,13L,13L,13L,13L,13L,13L,13L,
        14L,14L,14L,14L,14L,14L,14L,14L,14L,14L,
        15L,15L,15L,15L,15L,15L,15L,15L,15L,15L,
        16L,16L,16L,16L,16L,16L,16L,16L,16L,16L,
        17L,17L,17L,17L,17L,17L,17L,17L,17L,17L,
        18L,18L,18L,18L,18L,18L,18L,18L,18L,18L,
        19L,19L,19L,19L,19L,19L,19L,19L,19L,19L,
        20L,20L,20L,20L,20L,20L,20L,20L,20L,20L,
        21L,21L,21L,21L,21L,21L,21L,21L,21L,21L,
        22L,22L,22L,22L,22L,22L,22L,22L,22L,22L,
        23L,23L,23L,23L,23L,23L,23L,23L,23L,23L,
        24L,24L,24L,24L,24L,24L,24L,24L,24L,24L,
        25L,25L,25L,25L,25L,25L,25L,25L,25L,25L,
        26L,26L,26L,26L,26L,26L,26L,26L,26L,26L
      ),
      .Label = c(
        "1","2","3","4","5","6","7","8","9","10",
        "11","12","13","14","15","16","17","18","19","20",
        "21","22","23","24","25","26"
      ),
      class = "factor"
    ),
    precipitation = c(
      rep(0,110),
      1.59999999999997,0.800000000000011,0.600000000000023,0.199999999999989,
      0.399999999999977,0.400000000000034,1,0.799999999999955,0.400000000000034,
      0.800000000000011,rep(0,30),9.60000000000002,rep(0,19),1,rep(0,9),
      0.200000000000045,rep(0,29),0.200000002980232,rep(0,9)
    )
  ),
  class = c("tbl_df","tbl","data.frame"),
  row.names = c(NA,-260L)
)
解决方案

方法一:使用dplyr(tidyverse)

按周分组处理,先剔除无雨周,再保留首次降雨及之后的所有行:

library(dplyr)

result <- df %>%
  group_by(week) %>%
  # 过滤掉整周无降雨的组
  filter(any(precipitation > 0)) %>%
  # 筛选首次降雨及之后的行:累计降雨次数≥1即代表已过首次降雨节点
  filter(cumsum(precipitation > 0) >= 1) %>%
  ungroup()

# 验证week15结果(应保留第144-150行)
result %>% filter(week == "15")

逻辑说明:

  1. group_by(week):将数据按周拆分分组
  2. filter(any(precipitation > 0)):直接剔除无降雨的周(如week16)
  3. filter(cumsum(precipitation > 0) >= 1):通过累计统计降雨事件,首次降雨前累计值为0,首次降雨及之后累计值≥1,以此精准筛选目标时段

方法二:使用Base R

无需加载额外包,通过基础函数实现:

# 先标记每个周是否存在降雨
has_rain <- tapply(df$precipitation, df$week, function(x) any(x > 0))
# 筛选出有降雨的周的数据
df_filtered <- df[df$week %in% names(has_rain)[has_rain], ]

# 对每个有降雨的周,提取首次降雨至周末的行
result_base <- do.call(rbind, lapply(split(df_filtered, df_filtered$week), function(week_data) {
  first_rain_idx <- which(week_data$precipitation > 0)[1]
  week_data[first_rain_idx:nrow(week_data), ]
}))

# 验证week15结果
result_base[result_base$week == "15", ]

逻辑说明:

  1. tapply(...):统计每个周是否存在降雨记录
  2. 先筛选出所有有降雨的周的数据
  3. split(...)按周拆分数据,lapply(...)找到每个周首次降雨的索引,保留从该索引到末尾的行
  4. do.call(rbind, ...)将各周处理后的结果合并为最终数据框

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:57:00