Ответ 1
Попробуйте anti_join
от dplyr
library(dplyr)
anti_join(df, df1, by='heads')
У меня есть два кадра данных (df и df1). df1 - подмножество df. Я хочу получить кадр данных, который является дополнением к df1 в df. Например, пусть,
кадр данных df:
heads
row1
row2
row3
row4
row5
кадр данных df1:
heads
row3
row5
Тогда желаемый результат df2 равен:
heads
row1
row2
row4
Попробуйте anti_join
от dplyr
library(dplyr)
anti_join(df, df1, by='heads')
Вы также можете сделать некоторый тип анти-соединения с 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)
Попробуйте выполнить команду %in%
и отмените ее с помощью !
df[!df$heads %in% df1$heads,]
Другая опция, использующая базу R и функцию setdiff
:
df2 <- data.frame(heads = setdiff(df$heads, df1$heads))
setdiff
функционирует точно так, как вы предполагали; возьмите оба аргумента как множество и удалите все элементы во втором из первого.
Я нахожу setdiff
более читаемый tahtn %in%
и предпочитаю не требовать дополнительных библиотек, когда они мне не нужны, но ответ, который вы используете, во многом зависит от личного вкуса.
dplyr также имеет setdiff()
, который доставит вам
setdiff(bigFrame, smallFrame)
получает дополнительные записи в первой таблице.
поэтому для примера OP код будет читать setdiff(df, df1)
dplyr обладает большой функциональностью: для быстрого простого руководства см. здесь.
Другой вариант, создав функцию 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)