I'm working with a time series of 15-minute river flow observations collected over a 2-week period, and I'm trying to determine the dateTime of the peaks in river flow during this time. I've tried a number of packages/functions including ggpmisc::stat_peaks()
(example below), pracma::findpeaks()
, and cardidates::peakwindow()
, which claim to identify peaks in a time series, but I haven't been able to achieve realistic results with any of them. Can anyone advise how to identify realistic peaks in a time series using ggpmisc::stat_peaks()
? I'm also open to answers from other packages if ggpmisc
isn't the best option.
library(tidyverse)
library(dataRetrieval)
library(ggpmisc)
# 1. Download time series of river water flow
dat <- readNWISuv(siteNumbers = "01576381",
parameterCd = "00060",
startDate = "2024-04-01",
endDate = "2024-04-15",
tz = "America/New_York") %>%
renameNWISColumns() %>%
rename(flow = Flow_Inst) %>%
select(dateTime, flow)
# 2. See data structure
head(dat)
#> dateTime flow
#> 1 2024-04-01 00:00:00 25.0
#> 2 2024-04-01 00:15:00 25.6
#> 3 2024-04-01 00:30:00 25.0
#> 4 2024-04-01 00:45:00 25.6
#> 5 2024-04-01 01:00:00 25.1
#> 6 2024-04-01 01:15:00 25.6
# 3. Visualize time series of river flow over 2-week period
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
theme_bw()
# 4. Attempt to use stat_peaks to identify peaks in time series
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
stat_peaks(color = 'red') +
theme_bw()
# 4. Attempt to use stat_peaks to identify peaks in time series
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
stat_peaks(color = 'red',
strict = TRUE) +
theme_bw()
The ideal output (based on "eye-balling" the peaks) would look something like this: Created on 2025-03-17 with reprex v2.1.1
I'm working with a time series of 15-minute river flow observations collected over a 2-week period, and I'm trying to determine the dateTime of the peaks in river flow during this time. I've tried a number of packages/functions including ggpmisc::stat_peaks()
(example below), pracma::findpeaks()
, and cardidates::peakwindow()
, which claim to identify peaks in a time series, but I haven't been able to achieve realistic results with any of them. Can anyone advise how to identify realistic peaks in a time series using ggpmisc::stat_peaks()
? I'm also open to answers from other packages if ggpmisc
isn't the best option.
library(tidyverse)
library(dataRetrieval)
library(ggpmisc)
# 1. Download time series of river water flow
dat <- readNWISuv(siteNumbers = "01576381",
parameterCd = "00060",
startDate = "2024-04-01",
endDate = "2024-04-15",
tz = "America/New_York") %>%
renameNWISColumns() %>%
rename(flow = Flow_Inst) %>%
select(dateTime, flow)
# 2. See data structure
head(dat)
#> dateTime flow
#> 1 2024-04-01 00:00:00 25.0
#> 2 2024-04-01 00:15:00 25.6
#> 3 2024-04-01 00:30:00 25.0
#> 4 2024-04-01 00:45:00 25.6
#> 5 2024-04-01 01:00:00 25.1
#> 6 2024-04-01 01:15:00 25.6
# 3. Visualize time series of river flow over 2-week period
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
theme_bw()
# 4. Attempt to use stat_peaks to identify peaks in time series
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
stat_peaks(color = 'red') +
theme_bw()
# 4. Attempt to use stat_peaks to identify peaks in time series
dat %>%
ggplot(aes(x = dateTime, y = flow)) +
geom_line() +
stat_peaks(color = 'red',
strict = TRUE) +
theme_bw()
The ideal output (based on "eye-balling" the peaks) would look something like this: Created on 2025-03-17 with reprex v2.1.1
Share Improve this question edited Mar 17 at 18:33 tassones asked Mar 17 at 18:21 tassonestassones 1,77213 silver badges31 bronze badges 5- 1 What criteria did you use to determine your "ideal output"? – Scott Hunter Commented Mar 17 at 18:26
- Visual inspection - you can see the peaks in the time series plot. I'm looking for a way to extract these without having to "eye-ball" it. – tassones Commented Mar 17 at 18:27
- I'd try to put together a solution that first smooths the data set and then identifies local peaks. Don't know if there's something out there that already does this ... – Ben Bolker Commented Mar 17 at 18:36
- 1 This is incredible cool: stats.stackexchange/questions/36309/… and might work with some modifications – Friede Commented Mar 17 at 18:57
- 1 stackoverflow/questions/59557910/… – M-- Commented Mar 17 at 20:14
1 Answer
Reset to default 5cardidates::peakwindow
works fine, you just need to adjust mincut
to detect more or fewer peaks:
ggplot(dat, aes(x = dateTime, y = flow)) +
geom_line() + # geom_point() +
geom_point(
aes(as.POSIXct(x), y),
cardidates::peakwindow(dat$dateTime, dat$flow, mincut = 0.9)$peaks,
color = 'red'
) +
theme_bw()
One reason stat_peaks
struggles is that some of your peaks have duplicated values at the top, and algorithms looking for strict increases and decreases will fail.