Сравните два data.frames, чтобы найти строки в data.frame 1, которых нет в data.frame 2 - PullRequest
140 голосов
/ 03 июля 2010

У меня есть следующие 2 data.frames:

a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])

Я хочу найти строку a1, которой нет у a2.

Есть ли встроенная функция для этого типа операции?

(p.s: я написал решение для этого, мне просто любопытно, если кто-то уже сделал более искусный код)

Вот мое решение:

a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])

rows.in.a1.that.are.not.in.a2  <- function(a1,a2)
{
    a1.vec <- apply(a1, 1, paste, collapse = "")
    a2.vec <- apply(a2, 1, paste, collapse = "")
    a1.without.a2.rows <- a1[!a1.vec %in% a2.vec,]
    return(a1.without.a2.rows)
}
rows.in.a1.that.are.not.in.a2(a1,a2)

Ответы [ 12 ]

1 голос
/ 30 июля 2018

Использование subset:

missing<-subset(a1, !(a %in% a2$a))
1 голос
/ 14 апреля 2016

Еще одно решение, основанное на match_df в plyr.Вот plyr match_df:

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]
}

Мы можем изменить его, чтобы отрицать:

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]
}

Тогда:

diff <- negate_match_df(a1,a2)
...