Получите индексы одинаково строк из двух разных data.table's - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь сделать что-то подобное, как здесь:

R - индексы совпадения значений двух data.tables

Вот оригинальный воспроизводимый пример из вопроса выше:

S.disc <- c(2000,2000)
S.max  <- c(6200,2300)
S.min  <- c(700,100)

Traces.num <- 3
Class.str <- lapply(1:2,function(x) seq(S.min[x],S.max[x],S.disc[x]))
Class.inf <- seq_len(Traces.num)
Actions <- data.table(expand.grid(Class.inf, Class.str[[2]], Class.str[[1]], Class.str[[2]], Class.str[[1]])[,c(5,4,1,3,2)])
setnames(Actions,c("k1","k2","i","l1","l2"))
States <- unique(Actions[,list(k1,k2,i)])

Как начинающий R, я пытаюсь расширить этот пример для всех столбцов.

В моем случае мой первый data.table содержит 60 столбцов и 2,2 миллиона строк , Второй файл data.table является подмножеством первого, то есть он имеет такое же количество столбцов = 60, но гораздо меньше строк = 0,1 миллиона.

В конце я хотел бы иметь вектор с длиной data.table one = 2,2 миллиона, со значением TRUE, если строка одинаково существует где-то в data.table два, в противном случае FALSE.

Я сделал для l oop, но он крайне неэффективен и занимает несколько часов:

S.disc <- c(2000,2000)
S.max  <- c(6200,2300)
S.min  <- c(700,100)

Traces.num <- 3
Class.str <- lapply(1:2,function(x) seq(S.min[x],S.max[x],S.disc[x]))
Class.inf <- seq_len(Traces.num)
Actions <- data.table(expand.grid(Class.inf, Class.str[[2]], Class.str[[1]], Class.str[[2]], Class.str[[1]])[,c(5,4,1,3,2)])
setnames(Actions,c("k1","k2","i","l1","l2"))
States <- as.data.table(sample_n(Actions, 10))


idx_filter <- rep(NA,dim(Actions)[1])

for (a in 1:dim(Actions)[1]){
  for (b in 1:nrow(States))
    if (sum(Actions[a,] == States[b,]) == ncol(Actions)) { idx_filter[a] <- T }
}

idx_filter[is.na(idx_filter)] <- F

Как я могу сделать то же самое с data.table эффективно?

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

При использовании data.table> = 1.12.4 вы также можете использовать on=.NATURAL для объединения в пересекающихся столбцах (см. Пункт 10 в выпуске data.table_1.12.4 в https://cran.r-project.org/web/packages/data.table/news/news.html).

Следовательно, другой вариант:

Actions[, idx_filter := FALSE][States, on=.NATURAL, idx_filter := TRUE]
1 голос
/ 02 апреля 2020

Используя data.table, вы можете сначала создать столбец match из FALSE. Затем вы можете присоединиться с помощью States и установить строки, соответствующие TRUE. Затем выберите столбец логических значений match. Обратите внимание, что setkeyv будет сортировать таблицу данных Actions.

library(data.table)

setkeyv(setDT(Actions), names(Actions))
setkeyv(setDT(States), names(States))
Actions[ , match := FALSE][States, match := TRUE][ , match]

Редактировать : Как отмечено @ chinsoon12, вы можете использовать on = .NATURAL и пропустить setkeyv ( просто используйте setDT). Я добавил set.seed(123), чтобы сделать воспроизводимым. Похоже, тот же результат. Вот полный код, который я использую:

library(data.table)

set.seed(123)

S.disc <- c(2000,2000)
S.max  <- c(6200,2300)
S.min  <- c(700,100)

Traces.num <- 3
Class.str <- lapply(1:2,function(x) seq(S.min[x],S.max[x],S.disc[x]))
Class.inf <- seq_len(Traces.num)
Actions <- data.table(expand.grid(Class.inf, Class.str[[2]], Class.str[[1]], Class.str[[2]], Class.str[[1]])[,c(5,4,1,3,2)])
setnames(Actions,c("k1","k2","i","l1","l2"))
States <- as.data.table(sample_n(Actions, 10))

idx_filter <- rep(NA,dim(Actions)[1])

for (a in 1:dim(Actions)[1]){
  for (b in 1:nrow(States))
    if (sum(Actions[a,] == States[b,]) == ncol(Actions)) { idx_filter[a] <- T }
}

idx_filter[is.na(idx_filter)] <- F

#setkeyv(setDT(Actions), names(Actions))
#setkeyv(setDT(States), names(States))

setDT(Actions)
setDT(States)

result <- Actions[ , match := FALSE][States, on=.NATURAL, match := TRUE][ , match]
result

  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
 [28] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
 [55] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
 [82] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE

identical(result, idx_filter) 
[1] TRUE
...