R data.table - хранить только строки с одинаковым идентификатором (наиболее эффективное решение) - PullRequest
6 голосов
/ 09 апреля 2020

Я хочу использовать data.table для создания функции, которая хранит только те строки, в которых столбцы столбцов идентификаторов - сохраняются как вектор строк - дублируются. Обратите внимание, что там, где есть несколько столбцов идентификаторов, я хочу сохранить только те строки, в которых дублируется комбинация столбцов идентификаторов.

library(data.table)

dt <- data.table(x = c(1:5,5), y = rep(c(1,3,5), each = 2), z = rep(1:3, 2))

get_duplicate_id_rows1 <- function(dt_in, id_str) {
  dt_in[, if(.N > 1) .SD, by = id_str]
}

get_duplicate_id_rows1(dt, c("x", "y"))
#>    x y z
#> 1: 5 5 2
#> 2: 5 5 3

get_duplicate_id_rows1(dt[, .(x,y)], c("x", "y"))
#> Empty data.table (0 rows and 2 cols): x,y

Как и выше, моя первая попытка работает, когда в таблице данных есть один столбец без идентификатора. , Однако, когда все столбцы являются столбцами идентификаторов, таблица данных не имеет строк. Я думаю, это потому, что согласно ?data.table, .SD включает в себя все переменные исходной таблицы данных, кроме строк группировки. Следовательно, .SD имеет ноль столбцов, что, похоже, и вызывает мою проблему.

get_duplicate_id_rows2 <- function(dt_in, id_str) {
  dt_in[, if(.N > 1) .SD, by = id_str, .SDcols = names(dt_in)]
}

get_duplicate_id_rows2(dt, c("x", "y"))
#>    x y x y z
#> 1: 5 5 5 5 2
#> 2: 5 5 5 5 3

get_duplicate_id_rows2(dt[, .(x,y)], c("x", "y"))
#>    x y x y
#> 1: 5 5 5 5
#> 2: 5 5 5 5

Моя вторая попытка пытается обойти мои проблемы с моей первой попыткой с помощью .SDcols. Это решает проблему, когда все столбцы в моей таблице данных являются столбцами идентификаторов. Однако здесь имена столбцов в id_str дублируются.

Я думаю, это потому, что один набор имен столбцов взят из аргумента by, а другой набор имен столбцов - из .SDcols, хотя я не уверен в этом, потому что в моей первой попытке , в результирующей таблице данных было ноль строк , а не ноль столбцов .

Следовательно, я бы хотел понять, что здесь происходит, и что Наиболее эффективное решение моей проблемы - особенно для больших наборов данных, поэтому я перехожу с tidyverse на data.table.

Создано в 2020-04-09 представительный пакет (v0.3.0)

Ответы [ 2 ]

4 голосов
/ 09 апреля 2020

Мы можем использовать .I, чтобы получить индекс групп с частотным счетом больше 1, извлечь столбец и установить подмножество data.table

dt[dt[, .I[.N >1], .(x, y)]$V1]

ПРИМЕЧАНИЕ. Это должно быть быстрее, чем .SD

3 голосов
/ 09 апреля 2020

Вот еще один вариант:

dt[dt[rowid(x, y) > 1], on=.(x, y), .SD]

В этом примере ваше объяснение для возврата 0 строки является правильным. Так как столбцы группировки используются для группировки, они будут идентичны для каждой группы и могут быть доступны через .BY, и, следовательно, .SD не должны иметь эти столбцы для предотвращения дублирования.

По умолчанию, когда by используется, они также возвращаются как крайние левые столбцы в выводе, следовательно, в get_duplicate_id_rows2 вы видите x, y, а затем столбцы из .SD, как указано в .SDcols.

Наконец, в отношении эффективности Вы можете синхронизировать различные параметры, опубликованные здесь, используя microbenchmark, с вашим фактическим набором данных и обмениваться результатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...