Это самостоятельное декартово решение продукта. Я изменил ваш код, чтобы получить несколько значимых результатов. Я также думаю, что если у вас есть 8 миллионов строк, у вас будут проблемы с производительностью, когда n-й цикл зависит от n-го перед раздачей.
Изменения в структуре данных:
- Используется
sample
для получения некоторых повторов в data.table
- Упрощенные имена столбцов для функции data.table
setnames()
- Добавлено поле идентификатора
- Удален неиспользуемый столбец.
'%!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]
Я внес значительные изменения в ваш цикл.
- Назначено
c <- dt_loop$c[i]
, так как я не знаю, что там делал m.
- Удален первый оператор
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