Обозначение последовательности - PullRequest
0 голосов
/ 30 октября 2018

Я анализирую сигнал временного ряда. Я установил порог, чтобы отделить шум от базового шума. Чтобы идентифицировать свойства каждой последовательности сигналов (длительность, амплитуда, максимальный сигнал ...), я построил функцию для агрегирования всех точек сигнала, которые являются непрерывными, в виде различных «пиков». Несмотря на то, что эта функция выполняет то, что я хочу, мне было интересно, сможет ли кто-нибудь помочь мне сделать ее более эффективной - е. г. векторизация, потому что я стремлюсь запустить функцию на data.table из более чем 1M строк. Вот пример данных с функцией:

# Generate dummy data
x <- sin(seq(from = 0, to = 20, length.out = 200)) + rnorm(200, 0,0.1)
x <- zoo(x)
plot(x)


# Label each point as signal (== )1) or noise (0)

y <- ifelse(x > 0.5, 1, 0)

# Function to label each peak

peak_labeler <- function(x) {

  tmp <- NULL

  for (i in seq_along(x)) {

    if (x[i] == 0) { tmp[i] <- 0 } # If baseline, mark as 0

    if (x[i] == 1) {

      # If x[n] belongs to a peak
      if (i == 1) {tmp[i] <- 1} # Label as 1 at t0

      else{

        if (!exists("Peak")) {Peak <- 0}

        if (x[i - 1] == 0) {
          # if previous point is no peak, add as peak

          Peak <- Peak + 1
          tmp[i] <- Peak
        }

        if (x[i - 1] == 1) {
          tmp[i] <- Peak
        }
      }
    }

  }

  return(tmp)

  rm(tmp, Peak, i) # Garbage collection
}

# Label peaks

dummy <- data.frame(t = 1:200, x,y,tmp = peak_labeler(y))

# Show data

ggplot(dummy, aes(x = t, y = x)) +
  geom_point(aes(col = as.factor(tmp), group = 1))

enter image description here

1 Ответ

0 голосов
/ 30 октября 2018

Вот подход, использующий dplyr.

Тест в строке cross_threshold работает, оценивая, находится ли y с 0,5 стороны от предыдущего y. Если это так, знак двух слагаемых y - threshold и lag(y) - threshold будет отличаться, что приведет к ИСТИНА, умноженной на 1, чтобы стать 1. Если они на одной стороне 0,5, вы получите ЛОЖЬ и 0. Часть default = 0 имеет дело с первой строкой, где lag (y) не определено. Затем мы складываем, сколько кумулятивных крестов было, чтобы определить группу tmp.

library(dplyr)

threshold = 0.5 
dummy <- data.frame(t = 1:200, x, y) %>%
mutate(cross_threshold = 1 * (sign(y - threshold) != sign(lag(y, default = 0) - threshold)),
     # Line above now optional, just if we want to label all crossings
     up = 1 * ((y > threshold) & (lag(y) < threshold)),
     tmp = if_else(y > threshold, cumsum(up), 0))

ggplot(dummy, aes(x = t, y = x)) +
  geom_point(aes(col = as.factor(tmp), group = 1)) +
  geom_point(data = filter(dummy, cross_threshold == 1), shape = 21, size = 5)  

enter image description here

...