M Sandoval
M Sandoval

Reputation: 87

How to find the maximum peak and duration of a signal in R?

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:

enter image description here

I would like to know if:

  1. Is there any way to find these points accurately? I have tried multiple functions and packages in R, I have even tried Matlab and I have not been able to achieve precision.

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

Answers (1)

dcsuka
dcsuka

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

Related Questions