Как избежать этого для l oop в г - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь получить максимальные значения в столбце DT $ pna между пиковыми и минимальными событиями, которые находятся в соответствующих столбцах в data.table (т. Е. DT $ peak, DT $ through). Пики DT $ и впадины DT $ имеют строку «Пик» и «Падение» для обозначения начала и конца последующих событий. Это для l oop работает с очень уменьшенной выборкой, но потому что в data.table есть миллионы строк, которые нужны навсегда. Есть ли лучшее решение (возможно, с использованием таблицы данных), которое было бы более эффективным для получения максимального значения при этом условии?

for (i in 1:nrow(DT)) {
  if(is.na(DT$peak[i])) {
    next
  }
  if(DT$peak[i] == "peak") {
    e <- i + 15000
    for (j in i:e) {
      if(is.na(DT$trough[j])) {
        next
      }
      if(DT$trough[j] == "trough") {
        x <- (DT$pna[i:j])
      }
    }  
  }
  DT[i, max_insp := max(x)]
}

1 Ответ

1 голос
/ 18 марта 2020

Вот вариант:

DT[, rn := .I]

#use rolling join to find the nearest trough
DT[!is.na(peak), nt := DT[!is.na(trough)][.SD, on=.(rn), roll=-Inf, x.rn]]

#use non-equi join to find the max
DT[!is.na(peak), max_insp :=
    DT[.SD, on=.(rn>=rn, rn<=nt), by=.EACHI, max(x.pna)]$V1
]

Другой вариант (может быть быстрее, если у вас много пиков и впадин, но, возможно, менее читабелен):

DT[, c("pix", "tix") := .(nafill(replace(.I, is.na(peak), NA_integer_), "locf"), 
  nafill(replace(.I, is.na(trough), NA_integer_), "nocb"))]

iv <- DT[order(pix, tix, -pna)][{
    ri <- rleid(pix, tix)
    ri!=shift(ri, fill=0L) & !is.na(pix) & !is.na(tix)
  }]

DT[iv$pix, max_insp := iv$pna]

output:

    peak trough          pna rn nt max_insp
 1: <NA>   <NA>  1.262954285  1 NA       NA
 2: peak   <NA> -0.326233361  2 11 2.404653
 3: <NA>   <NA>  1.329799263  3 NA       NA
 4: <NA>   <NA>  1.272429321  4 NA       NA
 5: <NA>   <NA>  0.414641434  5 NA       NA
 6: <NA>   <NA> -1.539950042  6 NA       NA
 7: <NA>   <NA> -0.928567035  7 NA       NA
 8: <NA>   <NA> -0.294720447  8 NA       NA
 9: <NA>   <NA> -0.005767173  9 NA       NA
10: <NA>   <NA>  2.404653389 10 NA       NA
11: <NA> trough  0.763593461 11 NA       NA
12: <NA>   <NA> -0.799009249 12 NA       NA

данные:

library(data.table)
set.seed(0L)
DT <- data.table(peak=c(NA, "peak", rep(NA, 10)), 
    trough=c(rep(NA, 10), "trough", NA),
    pna=rnorm(12))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...