Как вычислить ширину импульса в форме волны? - PullRequest
0 голосов
/ 24 января 2019

Мне нужно вычислить ширину импульса в осциллограмме. Эти импульсы возникают во всем сигнале.

Я пытаюсь вычислить разницу между двумя последовательными значениями, и если она превышает значение (скажем, число), то я бы идентифицировал эту точку как начальную точку импульса и нашел бы точку, где она достигает того же уровня, что и раньше, и Я бы посчитал это конечной точкой пульса. Как только у меня будет начальная и конечная точки, я вычислю ширину (здесь это число точек между этими двумя точками)

Ответы [ 3 ]

0 голосов
/ 24 января 2019

ggpmisc() может предложить какое-то решение. Нужна небольшая оптимизация в span значении

wave <- c(1, 2, 1, 1.3, 1.2, 1, 2, 1, -25, -23, -24, -25, -24, -23, -26, -23, -17, -11, 2, 1, 1, 2)
wave = data.frame(wave = wave)

library(tidyverse)
#> Warning: package 'tibble' was built under R version 3.5.2
library(ggpmisc)
#> For news about 'ggpmisc', please, see https://www.r4photobiology.info/
#> For on-line documentation see https://docs.r4photobiology.info/ggpmisc/

with_valley <- 
   ggplot_build(
     ggplot(wave, aes(seq_along(wave), wave)) + geom_line() +
  stat_valleys(aes(seq_along(wave), wave), span = 10) 
   )
#> span increased to next odd value:  11


values <- with_valley$data[[2]]

values[2,"xintercept"]-values[1,"xintercept"]
#> [1] 6

Создано в 2019-01-24 пакетом Представить (v0.2.1)

0 голосов
/ 24 января 2019

Здесь есть возможность решения задачи с использованием vapply

starting_points <- which(c(abs(diff(pulse)) > 25L, FALSE))
res <- vapply(starting_points, function (k) {
  starting_value <- pulse[k]
  end_point <- min(intersect(which(pulse == starting_value), (k+1):length(pulse)))
  width <- end_point - k + 1
  c(start = k, end = end_point, width = width)
}, numeric(3))

# Results
res
#       [,1]
# start    8
# end     20
# width   13

# And here is result with a little more data
# setting pulse <- rep(pulse, 3L)
t(res)
#      start end width
# [1,]     8  20    13
# [2,]    30  42    13
# [3,]    52  64    13

с данными

pulse <- c(1, 2, 1, 1.3, 1.2, 1, 2, 1, -25, -23, -24, -25, -24, -23, -26, -23, -17, -11, 2, 1, 1, 2)
0 голосов
/ 24 января 2019

Вот решение с общим циклом for().Обратите внимание, что это, вероятно, будет медленно и неэффективно для больших данных.

# example vector
x <- c(1, 2, 1, 1.3, 1.2, 1, 2, 1, -25, -23, -24, -25, -24, -23, -26, -23, -17, -11, 2, 1, 1, 2)

# initialize data frame with columns start (starting position of pulse), end (end position of pulse) and width (width of pulse)
pulsewidth <- data.frame(start = numeric(),
                         end = numeric(),
                         width = numeric())

# initialize temporary saving element for starting position
temp <- NA

# loop over position 2 to end of vector, compare lagged values, store position if pulse starts
for(i in 2:length(x)){
  if(abs(x[i] - x[i-1]) >= 25){
    temp <- i-1 # here you could use temp <- i instead, depending on your definition
  }
  if(!is.na(temp)){
    if(x[i] >= x[temp]){
      pulsewidth[nrow(pulsewidth)+1,] <- c(temp, i, i - temp)
      temp <- NA
    }
  }
}

Результат:

> pulsewidth
  start end width
1     8  19    11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...