使用R语言dplyr包按多条件提取各站点年首个目标日序
问题:提取河流温度峰值前后特定游程的首个年日序
现有一个包含两条河流两年日温度时间序列的DataFrame,已标记温度处于峰值上下的状态,且创建了温度≤10℃的游程ID列(run)。需按站点(site_no)和年份(year)分组,获取满足以下条件的首个年日序(doy):
- 处于峰值前(
below_peak == TRUE)且对应run为该组峰值前的最大值; - 处于峰值后(
after_peak == TRUE)且对应run为该组峰值后的最大值。
示例数据获取代码
library(ggplot2) library(lubridate) library(dplyr) library(dataRetrieval) siteNumber <- c("01432805","01388000") # 美国地质调查局站点编号 parameterCd <- "00010" # 温度参数码 statCd <- "00003" # 均值统计码 startDate <- "1996-01-01" endDate <- "1997-12-31" dat <- readNWISdv(siteNumber, parameterCd, startDate, endDate, statCd=statCd) # 从USGS获取时间序列数据 dat <- dat[,c(2:4)] colnames(dat)[3] <- "temperature" # 可视化时间序列 ggplot(data = dat, aes(x = Date, y = temperature)) + geom_point() + theme_bw() + facet_wrap(~site_no)
预处理代码
dat <- dat %>% mutate(year = year(Date), doy = yday(Date)) %>% # doy = 年日序 group_by(site_no, year) %>% mutate(lt_10 = temperature <= 10, peak_doy = doy[which.max(temperature)], below_peak = doy < peak_doy, after_peak = doy > peak_doy, run = data.table::rleid(lt_10)) View(dat)
解决方案代码
# 按站点和年份分组,提取目标doy result <- dat %>% group_by(site_no, year) %>% # 提取峰值前最大run对应的首个doy filter(below_peak, run == max(run[below_peak], na.rm = TRUE)) %>% slice_head(n = 1) %>% select(site_no, year, doy_below = doy) %>% # 合并峰值后最大run对应的首个doy left_join( dat %>% group_by(site_no, year) %>% filter(after_peak, run == max(run[after_peak], na.rm = TRUE)) %>% slice_head(n = 1) %>% select(site_no, year, doy_after = doy), by = c("site_no", "year") ) %>% ungroup() print(result)
理想输出
site_no year doy_below doy_after 1 01388000 1996 111 317 2 01388000 1997 112 312 3 01432805 1996 137 315 4 01432805 1997 130 294
说明:
doy_below:按site_no、year分组后,满足below_peak == TRUE且run为该组峰值前最大值的首行doy;doy_after:按site_no、year分组后,满足after_peak == TRUE且run为该组峰值后最大值的首行doy。
内容的提问来源于stack exchange,提问作者tassones
相关产品推荐
相关产品推荐

