Самый быстрый способ удалить строки из очень большого информационного кадра, соответствующего другому информационному - PullRequest
0 голосов
/ 14 января 2020

Какая самая быстрая функция в r для удаления строк в кадре данных, если те же два первых столбца находятся в другом кадре данных. Например, если кадр данных A такой, как показано ниже (с дополнительными столбцами информации):

    NAME    SURENAME
    John    Beer
    Rose    Pitt
    Bob     Kin
    Charile Kind
    Smith   Red
    Brad    Tea
    Kale    Joe
    Ana     Bread
    Lauren  Old
    Mike    Karl 

и B, как показано ниже:

NAME    SURENAME
Rose    Pitt
Smith   Red
Mike    Karl

, я хочу, чтобы B был удален из A в быть похожим на:

    NAME    SURENAME
    John    Beer
    Bob     Kin
    Charile Kind
    Brad    Tea
    Kale    Joe
    Ana     Bread
    Lauren  Old

Так что в моем случае A имеет 2 миллиона строк (и 10 других столбцов), а B имеет 200 000 строк (все уникальные имена и фамилии).

Ответы [ 2 ]

1 голос
/ 14 января 2020

Протестирован эталонный тест, фильтрующий фрейм данных из 2 миллионов строк на 200 000 строк, как указано в исходном сообщении, где вы можете четко увидеть скорость data.table относительно dplyr. Учитывая огромное время, которое потребовалось dplyr функциям, особенно set_diff, я запускал каждую из них только один раз.

rbenchmark::benchmark(
  "dplyr_anti_join" = {
    set.seed(1)
    df <- data.frame(a = letters[runif(10000000, min = 1, max = 26)],
                     b = runif(100000000, 1, 200000))

    indices <- data.frame(a = letters[runif(200000, min = 1, max = 26)],
                          b = 1:200000)
    dplyr::anti_join(df, indices, by = c("a", "b"))
  },
  "dplyr_set_diff" = {
    set.seed(1)
    df <- data.frame(a = letters[runif(10000000, min = 1, max = 26)],
                     b = runif(100000000, 1, 200000))

    indices <- data.frame(a = letters[runif(200000, min = 1, max = 26)],
                          b = 1:200000)
    dplyr::setdiff(df, indices)
  },
  "dt" = {
    set.seed(1)
    library(data.table)
    df <- data.table(a = letters[runif(10000000, min = 1, max = 26)],
                     b = runif(100000000, 1, 200000))

    indices <- data.table(a = letters[runif(200000, min = 1, max = 26)],
                          b = 1:200000)
    fsetdiff(df, indices)
  },
  replications = 1
)

#>              test replications elapsed relative user.self sys.self user.child sys.child
#> 1 dplyr_anti_join            1  637.06   13.165    596.86    11.50         NA        NA
#> 2  dplyr_set_diff            1 9981.93  206.281    320.67     4.66         NA        NA
#> 3              dt            1   48.39    1.000     80.61     8.73         NA        NA
1 голос
/ 14 января 2020

Возможно, вы можете попробовать приведенный ниже код, используя setdiff() из пакета dplyr, но вам нужно проверить его скорость для большого фрейма данных (тогда я не уверен насчет его производительности)

C <- dplyr::setdiff(A,B)

такой, что

> C
     NAME SURENAME
1    John     Beer
2     Bob      Kin
3 Charile     Kind
4    Brad      Tea
5    Kale      Joe
6     Ana    Bread
7  Lauren      Old

ДАННЫЕ

A <- structure(list(NAME = c("John", "Rose", "Bob", "Charile", "Smith", 
"Brad", "Kale", "Ana", "Lauren", "Mike"), SURENAME = c("Beer", 
"Pitt", "Kin", "Kind", "Red", "Tea", "Joe", "Bread", "Old", "Karl"
)), class = "data.frame", row.names = c(NA, -10L))

B <- structure(list(NAME = c("Rose", "Smith", "Mike"), SURENAME = c("Pitt", 
"Red", "Karl")), class = "data.frame", row.names = c(NA, -3L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...