Reputation: 87
I am trying to find the duration in seconds of a signal, to do this I use a function from (Finding start and end of a peak in time series in R).
y = signal
y$startEndPeak <- NA
which.min(abs(diff(y$peak)))
i.mins <- which(diff(sign(diff(c(Inf, y$peak, Inf)))) == 2)
i.mins
i.mx <- which.max(y$peak)
i.mx
y$startEndPeak[i.mx]<- "peak"
ind <- sort(c(i.mins, i.mx))
ix <- ind[which(ind == i.mx) + c(-1, 1)]
ix
y$startEndPeak[ix]<- c("start", "end")
## start, end, peak
ix2<- c(ix,i.mx)
ix2
dat<- y[ix2,]
dat
The output:
Time | Peak | startEndPeak |
---|---|---|
4.46 | -649.774 | start |
5.86 | 19791.226 | end |
5.00 | 48655.226 | peak |
I was able to detect the maximum point (peak), but the code fails to detect correctly the minimum points to the peak. Thus, it is impossible to determine correctly the duration of the signal. This is what I want to identify, x= time, y= signal:
I would like to know if:
It may be possible to draw a line at the minimum point on the left of the peak and find the intersection point on the other side of the sign.
You can download one example of the signal here
Thank you for your time!
Upvotes: 2
Views: 506
Reputation: 2997
Here is a simple solution using pspline
and the time series derivative of the data. You may have to tune the cutoff values and the ignore region judging by other peaks as well:
get_duration <- function(df) {
deriv <- as.vector(predict(sm.spline(df$time, df$peak), df$time, 1))
start <- which.max(deriv > 7000)
ignore_region <- 60
end <- start + ignore_region + which.max(deriv[(start + ignore_region):length(deriv)] > -100)
df$time[end] - df$time[start]
}
get_duration(df)
#[1] 3.22
Upvotes: 1