Как ускорить последовательный анализ в R? - PullRequest
0 голосов
/ 17 мая 2019

Мне нужно последовательно анализировать набор данных при использовании подрезультатов операций ранее.

Поскольку я известен R, я решил поработать с этим, и одним из решений, которое я попробовал, является использование цикла for.

В наборе данных, который я перебираю, содержится около 8 миллионов строк с 4 столбцами.

Я использую data.table, и переменные имеют тип символов например. "XXXXXXXXX"

Я попытался выполнить цикл, но это занимает примерно 0,7 секунды за цикл, из которого операция "<-" занимает полсекунды. </p>

Кто-нибудь может порекомендовать лучшую технику. Потенциально rcpp, применять или как?? 1011 *

Спасибо за вашу поддержку,

Хольгер

'%!in%' <- function(x,y)!('%in%'(x,y))
library('data.table')    


dt_loop <- data.table(
              paste0("XXXXXXXXXX", 1:80000000),
              paste0("YXXXXXXXXX", 1:80000000),
              paste0("ZXXXXXXXXX", 1:80000000),
              paste0("AXXXXXXXXX", 1:80000000)
      )

    colnames(dt_loop)[colnames(dt_loop)=="V1"] <- "m"
    colnames(dt_loop)[colnames(dt_loop)=="V2"] <- "c"
    colnames(dt_loop)[colnames(dt_loop)=="V3"] <- "ma"
    colnames(dt_loop)[colnames(dt_loop)=="V4"] <- "unused"


    for(i in 1:nrow(dt_loop)){
      m <- dt_loop$m[i]
      c <- dt_loop$m[i]

      if(m %!in% dt_loop$ma[1:i] & c %!in% dt_loop$ma[1:i]){
        dt_loop$ma[i] <- m
      } else { 
        if(m %in% dt_loop$ma[1:i]){
          dt_loop$ma[i] <- m
        } else {
          dt_loop$ma[i] <- c
        }
      } 
    }

1 Ответ

0 голосов
/ 18 мая 2019

Это самостоятельное декартово решение продукта. Я изменил ваш код, чтобы получить несколько значимых результатов. Я также думаю, что если у вас есть 8 миллионов строк, у вас будут проблемы с производительностью, когда n-й цикл зависит от n-го перед раздачей.

Изменения в структуре данных:

  1. Используется sample для получения некоторых повторов в data.table
  2. Упрощенные имена столбцов для функции data.table setnames()
  3. Добавлено поле идентификатора
  4. Удален неиспользуемый столбец.
'%!in%' <- function(x,y)!('%in%'(x,y))
library('data.table')    

# Generate Data -----------------------------------------------------------

set.seed(1)
n_rows <- 10
dt_loop <- data.table(
  sample(paste0("X", 1:n_rows), n_rows, replace = T),
  sample(paste0("Y", 1:n_rows), n_rows, replace = T),
  sample(paste0("X", 1:n_rows), n_rows, replace = T)
)

setnames(dt_loop, c('m', 'c', 'ma'))
dt_loop[, ID := .I]

Я внес значительные изменения в ваш цикл.

  1. Назначено c <- dt_loop$c[i], так как я не знаю, что там делал m.
  2. Удален первый оператор if из-за нового присваивания c.
# Original loop with Minor Mod --------------------------------------------

for(i in 1:nrow(dt_loop)){
  m <- dt_loop$m[i]
  c <- dt_loop$c[i] #changed to c instead of m

#Removed first ifelse condition
  #as it didn't make sense as originally constructed

  # if(m %!in% dt_loop$ma[1:i] & c %!in% dt_loop$ma[1:i]){
    # dt_loop$ma2[i] <- m
  # } else {
    if(m %in% dt_loop$ma[1:i]){
      dt_loop$ma2[i] <- m
    } else {
      dt_loop$ma2[i] <- c
    }
  # }
}
dt_loop

      m   c  ma ID ma2
 1:  X3  Y3 X10  1  Y3
 2:  X4  Y2  X3  2  Y2
 3:  X6  Y7  X7  3  Y7
 4: X10  Y4  X2  4 X10
 5:  X3  Y8  X3  5  X3
 6:  X9  Y5  X4  6  Y5
 7: X10  Y8  X1  7 X10
 8:  X7 Y10  X4  8  X7
 9:  X7  Y4  X9  9  X7
10:  X1  Y8  X4 10  X1

Самостоятельное объединение кажется более быстрым, чем цикл, когда я увеличиваю строки до 10 000, но все равно замедляется. Следует отметить, что вы можете видеть, когда происходит дублирование с ma, потому что декартово произведение расширяет результаты, так что вы получаете N == 2.

Я считаю, что есть способы заставить самообъединение работать так, чтобы вы получили только N-й ряд, который должен снять некоторое давление.

dt_loop[dt_loop
        , on = .(ID <= ID
                 , ma = m)
        , .(.N
            ,i.ma2 #for comparison - remove
            ,ma3 = ifelse(is.na(x.ID), i.c, i.m)
            ,i.ID, i.m, i.c, i.ma
            ,x.ID, x.m, x.c, x.ma 
        )
        , by = .EACHI
        , allow.cartesian = T]

    ID  ma N i.ma2 ma3 i.ID i.m i.c i.ma x.ID  x.m  x.c x.ma
 1:  1  X3 0    Y3  Y3    1  X3  Y3  X10   NA <NA> <NA> <NA>
 2:  2  X4 0    Y2  Y2    2  X4  Y2   X3   NA <NA> <NA> <NA>
 3:  3  X6 0    Y7  Y7    3  X6  Y7   X7   NA <NA> <NA> <NA>
 4:  4 X10 1   X10 X10    4 X10  Y4   X2    1   X3   Y3  X10
 5:  5  X3 2    X3  X3    5  X3  Y8   X3    2   X4   Y2   X3
 6:  5  X3 2    X3  X3    5  X3  Y8   X3    5   X3   Y8   X3
 7:  6  X9 0    Y5  Y5    6  X9  Y5   X4   NA <NA> <NA> <NA>
 8:  7 X10 1   X10 X10    7 X10  Y8   X1    1   X3   Y3  X10
 9:  8  X7 1    X7  X7    8  X7 Y10   X4    3   X6   Y7   X7
10:  9  X7 1    X7  X7    9  X7  Y4   X9    3   X6   Y7   X7
11: 10  X1 1    X1  X1   10  X1  Y8   X4    7  X10   Y8   X1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...