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
相关产品推荐
相关产品推荐

