Подтвердить что ты не робот

Найдите дополнение к кадру данных (антисоединение)

У меня есть два кадра данных (df и df1). df1 - подмножество df. Я хочу получить кадр данных, который является дополнением к df1 в df. Например, пусть,

кадр данных df:

heads
row1
row2
row3
row4
row5

кадр данных df1:

heads
row3
row5

Тогда желаемый результат df2 равен:

heads
row1
row2
row4
4b9b3361

Ответ 1

Попробуйте anti_join от dplyr

library(dplyr)
anti_join(df, df1, by='heads')

Ответ 2

Вы также можете сделать некоторый тип анти-соединения с data.table двоичным соединением

library(data.table)
setkey(setDT(df), heads)[!df1]
#    heads
# 1:  row1
# 2:  row2
# 3:  row4

EDIT: Запуск data.table v1.9.6 + мы можем присоединить data.tables без установки клавиш при использовании on

setDT(df)[!df1, on = "heads"]

EDIT2: Вводится начальная информация .table v1.9.8 + fsetdiff, которая в основном представляет собой вариацию решения выше, только по всем именам столбцов таблицы x data.table, например x[!y, on = names(x)]. Если all установлено на FALSE (поведение по умолчанию), тогда будут возвращены только уникальные строки в x. Для случая только одного столбца в каждой таблице данных следующее будет эквивалентно предыдущим решениям

fsetdiff(df, df1, all = TRUE)

Ответ 3

Попробуйте выполнить команду %in% и отмените ее с помощью !

df[!df$heads %in% df1$heads,]

Ответ 4

Другая опция, использующая базу R и функцию setdiff:

df2 <- data.frame(heads = setdiff(df$heads, df1$heads))

setdiff функционирует точно так, как вы предполагали; возьмите оба аргумента как множество и удалите все элементы во втором из первого.

Я нахожу setdiff более читаемый tahtn %in% и предпочитаю не требовать дополнительных библиотек, когда они мне не нужны, но ответ, который вы используете, во многом зависит от личного вкуса.

Ответ 5

dplyr также имеет setdiff(), который доставит вам

введите описание изображения здесь

setdiff(bigFrame, smallFrame) получает дополнительные записи в первой таблице.

поэтому для примера OP код будет читать setdiff(df, df1)

dplyr обладает большой функциональностью: для быстрого простого руководства см. здесь.

Ответ 6

Другой вариант, создав функцию negate_match_df, управляя кодом match_df пакета plyr.

library(plyr)
negate_match_df <- function (x, y, on = NULL) 
{
if (is.null(on)) {
    on <- intersect(names(x), names(y))
    message("Matching on: ", paste(on, collapse = ", "))
}
keys <- join.keys(x, y, on)
x[!keys$x %in% keys$y, , drop = FALSE]
}

Данные

df <- read.table(text ="heads
row1
row2
row3
row4
row5",header=TRUE)

df1 <- read.table(text ="heads
row3
row5",header=TRUE)

Выход

negate_match_df(df,df1)