У меня есть следующие 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 не имеет.
Есть ли встроенная функция для этого типа операции?
(ps: я действительно написал решение для этого, мне просто любопытно, если кто-то уже сделал более разработанный код)
Вот мое решение:
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)
a2 <- data.frame(a = c(1:3, 1), b = c(letters[1:3], "c"))
. Оставьa1
то же самое. Теперь попробуйте сравнение. Даже при чтении опций мне не ясно, как правильно перечислять только общие элементы.SQLDF
обеспечивает хорошее решениеИ строки, которые находятся в обоих фреймах данных:
Новая версия
dplyr
имеет функциюanti_join
, для именно таких сравненийИ
semi_join
отфильтровать строкиa1
, которые также находятся вa2
источник
anti_join
иsemi_join
!В дплыр :
В основном,
setdiff(bigFrame, smallFrame)
вы получаете дополнительные записи в первой таблице.В SQLverse это называется
Для хорошего описания всех вариантов объединения и заданных тем, это одно из лучших резюме, которое я когда-либо видел, составленное на сегодняшний день: http://www.vertabelo.com/blog/technical-articles/sql-joins
Но вернемся к этому вопросу - вот результаты для
setdiff()
кода при использовании данных ОП:Или даже
anti_join(a1,a2)
получите те же результаты.Для получения дополнительной информации: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
источник
a1
, которых нетa2
, разве вы не хотите использовать что-то подобноеsemi_join(a1, a2, by = c('a','b'))
? В ответе «Рикард» я вижу, чтоsemi_join
было предложено.setdiff()
функции, которая работает с двумя векторами: stat.ethz.ch/R-manual/R-devel/library/base/html/sets.html . Может быть, вы загрузили библиотеку lubridate после dplyr, и она предлагает ее в качестве источника в списке tabcomplete?Это, конечно, неэффективно для этой конкретной цели, но я часто делаю в этих ситуациях вставку переменных индикатора в каждый data.frame, а затем слияние:
пропущенные значения в include_a1 заметят, какие строки отсутствуют в a1. аналогично для а2.
Одна проблема с вашим решением состоит в том, что порядок столбцов должен совпадать. Другая проблема заключается в том, что легко представить себе ситуации, когда строки кодируются как одинаковые, хотя на самом деле они разные. Преимущество использования слияния состоит в том, что вы получаете бесплатно все проверки ошибок, которые необходимы для хорошего решения.
источник
included_a1
? : - /Я написал пакет ( https://github.com/alexsanjoseph/compareDF ), поскольку у меня была та же проблема.
Более сложный пример:
В пакете также есть команда html_output для быстрой проверки
источник
The two data frames have different columns!
Вы можете использовать
daff
пакет (который оборачиваетdaff.js
библиотеку, используяV8
пакет ):создает следующий объект разницы:
Табличный формат diff описан здесь и должен быть довольно понятным. Строки с
+++
в первом столбце@@
те, которые являются новыми,a1
а не присутствуют вa2
.Объект разницы можно использовать для
patch_data()
хранения разницы в целях документирования с использованиемwrite_diff()
или для визуализации разницы с использованиемrender_diff()
:генерирует аккуратный вывод HTML:
источник
Используя
diffobj
пакет:источник
Я адаптировал
merge
функцию, чтобы получить эту функциональность. На больших фреймах данных он использует меньше памяти, чем решение полного слияния. И я могу играть с именами ключевых столбцов.Другим решением является использование библиотеки
prob
.источник
Данные вашего примера не имеют дубликатов, но ваше решение обрабатывает их автоматически. Это означает, что потенциально некоторые ответы не будут соответствовать результатам вашей функции в случае дубликатов.
Вот мое решение, адрес которого дублируется так же, как ваш. Это также отлично масштабируется!
Требуется data.table 1.9.8+
источник
Возможно, это слишком упрощенно, но я использовал это решение и считаю его очень полезным, когда у меня есть первичный ключ, который я могу использовать для сравнения наборов данных. Надеюсь, это поможет.
источник
Еще одно решение, основанное на match_df в plyr. Вот plyr match_df:
Мы можем изменить это, чтобы отрицать:
Затем:
источник
Использование
subset
:источник
Следующий код использует оба
data.table
иfastmatch
для увеличения скорости.источник