J'ai les 2 data.frames suivants:
a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])
Je veux trouver la ligne a1 que a2 n'a pas.
Existe-t-il une fonction intégrée pour ce type d'opération?
(ps: j'ai écrit une solution pour cela, je suis simplement curieux de savoir si quelqu'un a déjà fait un code plus élaboré)
Voici ma solution:
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"))
. Laisseza1
le même. Maintenant, essayez la comparaison. Même en lisant les options, je ne vois pas clairement quelle est la bonne façon de ne lister que les éléments communs.SQLDF
fournit une belle solutionEt les lignes qui sont dans les deux blocs de données:
La nouvelle version de
dplyr
a une fonctionanti_join
,, pour exactement ce genre de comparaisonsEt
semi_join
pour filtrer les lignesa1
qui sont également ena2
la source
anti_join
etsemi_join
!Dans dplyr :
Fondamentalement,
setdiff(bigFrame, smallFrame)
vous obtenez les enregistrements supplémentaires dans la première table.Dans le SQLverse, cela s'appelle un
Pour une bonne description de toutes les options de jointure et des sujets définis, c'est l'un des meilleurs résumés que j'ai vu assemblés à ce jour: http://www.vertabelo.com/blog/technical-articles/sql-joins
Mais revenons à cette question - voici les résultats pour le
setdiff()
code lors de l'utilisation des données de l'OP:Ou même
anti_join(a1,a2)
vous obtiendrez les mêmes résultats.Pour plus d'informations: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
la source
a1
qui ne le sont pasa2
, ne voulez-vous pas utiliser quelque chose commesemi_join(a1, a2, by = c('a','b'))
? Dans la réponse de «Rickard», je vois que cela asemi_join
été suggéré.setdiff()
fonction de base qui fonctionne sur deux vecteurs: stat.ethz.ch/R-manual/R-devel/library/base/html/sets.html . Peut-être avez-vous chargé la bibliothèque lubridate après dplyr et la suggère-t-elle comme source dans la liste tabcomplete?Ce n'est certainement pas efficace dans ce but précis, mais ce que je fais souvent dans ces situations est d'insérer des variables indicatrices dans chaque data.frame puis de fusionner:
les valeurs manquantes dans included_a1 noteront les lignes manquantes dans a1. de même pour a2.
Un problème avec votre solution est que les ordres de colonnes doivent correspondre. Un autre problème est qu'il est facile d'imaginer des situations où les lignes sont codées de la même manière alors qu'en fait sont différentes. L'avantage d'utiliser la fusion est que vous obtenez gratuitement toutes les vérifications d'erreurs nécessaires à une bonne solution.
la source
included_a1
? : - /J'ai écrit un package ( https://github.com/alexsanjoseph/compareDF ) car j'ai eu le même problème.
Un exemple plus compliqué:
Le package a également une commande html_output pour une vérification rapide
la source
The two data frames have different columns!
Vous pouvez utiliser le
daff
package (qui enveloppe ladaff.js
bibliothèque à l'aide duV8
package ):produit l'objet de différence suivant:
Le format de diff tabulaire est décrit ici et devrait être assez explicite. Les lignes avec
+++
dans la première colonne@@
sont celles qui sont nouvellesa1
et non présentes dansa2
.L'objet difference peut être utilisé pour
patch_data()
stocker la différence à des fins de documentation en utilisantwrite_diff()
ou pour visualiser la différence en utilisantrender_diff()
:génère une sortie HTML soignée:
la source
Utilisation du
diffobj
package:la source
J'ai adapté le
merge
fonction pour obtenir cette fonctionnalité. Sur des données plus volumineuses, elle utilise moins de mémoire que la solution de fusion complète. Et je peux jouer avec les noms des colonnes clés.Une autre solution consiste à utiliser la bibliothèque
prob
.la source
Vos données d'exemple n'ont pas de doublons, mais votre solution les gère automatiquement. Cela signifie que potentiellement certaines des réponses ne correspondent pas aux résultats de votre fonction en cas de doublons.
Voici ma solution dont l'adresse se duplique de la même manière que la vôtre. Il évolue également très bien!
Il a besoin de data.table 1.9.8+
la source
C'est peut-être trop simpliste, mais j'ai utilisé cette solution et je la trouve très utile lorsque j'ai une clé primaire que je peux utiliser pour comparer des ensembles de données. J'espère que cela peut vous aider.
la source
Encore une autre solution basée sur match_df dans plyr. Voici le match_df de plyr:
Nous pouvons le modifier pour annuler:
Ensuite:
la source
Utilisation
subset
:la source
Le code suivant utilise à la fois
data.table
etfastmatch
pour une vitesse accrue.la source