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

R语言多TRUE结果取首个:河流水温阈值年度日序计算问题

河流水温持续阈值起始日计算问题解决

问题说明

我有一个包含某条河流两年日温度时间序列的dataframe,需计算两个年度日序(doy):

  • 水温持续≥10℃的起始日(持续指在年度峰值水温前不再低于10℃);
  • 水温持续≤10℃的起始日(持续指至次年不再高于10℃)。

计算第2项时,原代码中test_below == 14会出现多个TRUE结果导致报错,需实现多TRUE结果时选取首个值的逻辑,同时保留14天连续阈值设定。

示例数据集代码

library(ggplot2)
library(lubridate)
library(dplyr)
library(dataRetrieval)

siteNumber <- "01417500"
parameterCd <- "00010" # 水温
statCd <- "00003" # 平均值
startDate <- "2015-01-01"
endDate <- "2016-12-31"

dat <- readNWISdv(siteNumber, parameterCd, startDate, endDate, statCd=statCd)
dat <- dat[,c(2:4)]
colnames(dat)[3] <- "temperature"

# 可视化时间序列
ggplot(data = dat, aes(x = Date, y = temperature)) +
  geom_point() +
  theme_bw()

修正后的计算代码

dat %>%
  mutate(year = year(Date),
         doy = yday(Date)) %>%
  group_by(year) %>%
  mutate(gt_10 = temperature >= 10, # 水温≥10℃标记
         lt_10 = temperature <= 10, # 水温≤10℃标记
         peak_doy = doy[which.max(temperature)], # 年度峰值水温对应的日序
         below_peak = doy < peak_doy, # 是否在峰值水温之前
         after_peak = doy > peak_doy, # 是否在峰值水温之后
         # 统计连续≥10℃的天数
         test_above = ave(gt_10, cumsum(!gt_10), FUN = cumsum),
         # 统计连续≤10℃的天数
         test_below = ave(lt_10, cumsum(!lt_10), FUN = cumsum)) %>%
  summarise(
    # 提取峰值前首次连续14天≥10℃的起始日(第1天)
    first_above_10_sustained = first(doy[below_peak & test_above == 14]) - 13,
    # 提取峰值后首次连续14天≤10℃的起始日(第1天)
    first_below_10_sustained = first(doy[after_peak & test_below == 14]) - 13
  )

关键修改说明

  • 使用first()函数提取符合条件的首个日序值,解决了原代码中多个匹配结果导致的报错问题;
  • 保留了14天连续阈值的统计逻辑,通过ave()函数计算连续达标天数,确保筛选的是首次满足连续14天的节点;
  • 针对峰值前后的范围过滤逻辑保持不变,保证计算的起始日符合业务定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:25:36