J'ai 2 dfs comme celui-ci
for (i in 1:5){
if (for (j in 1:5){
df[i,1:2] == df2[j,1:2]})
print("true")
}
Je veux trouver s'il y a une ligne dans df 1 qui == une ligne dans df2 pour les colonnes A et B. Vous pouvez voir que df1 [4,1: 2] == df2 [2,1: 2]
J'ai essayé
df1 <- data.frame("A" = c(1,2,3,4,5), "B" = c(10,20,30,40,50), "C" = c(6,7,8,9,11))
df2 <- data.frame("A" = c(10,4,30,20,50), "B" = c(1,40,3,7,5)), "C" = c(12,13,14,15))
Mais cela me donne cette erreur: Erreur dans if (for (j in 1: 5) {: l'argument est de longueur zéro
4 Réponses :
Vous pouvez lier les colonnes A et B en ligne et utiliser anyDuplicated():
anyDuplicated(rbind(unique(df1[1:2]), unique(df2[1:2]))) > 0
S'il y a des doublons potentiels dans les blocs de données, vous devrez les créer unique d'abord:
anyDuplicated(rbind(df1[1:2], df2[1:2])) > 0 [1] TRUE
Vous pouvez coller les valeurs par ligne et vérifier les doublons en utilisant % in% :
dplyr::semi_join(df1, df2, by = c('A', 'B'))
Si vous n'avez besoin que d'un seul TRUE / FALSE valeur
dplyr::anti_join(df1, df2, by = c('A', 'B'))
# A B C
#1 1 10 6
#2 2 20 7
#3 3 30 8
#4 5 50 11
Si vous souhaitez supprimer des lignes dans df1 qui est présent dans df2 vous pouvez utiliser anti_join de dplyr.
any(do.call(paste, df1[1:2]) %in% do.call(paste, df2[1:2])) #[1] TRUE
Pour obtenir lignes communes que vous pouvez utiliser semi_join / inner_join :
df1[do.call(paste, df1[1:2]) %in% do.call(paste, df2[1:2]),] # A B C #4 4 40 9
Cela a parfaitement fonctionné! Pouvez-vous me dire comment je supprime ces lignes résultant de votre première ligne de code?
@ApoloReis Vous pouvez annuler la condition? df1 [! do.call (coller, df1 [1: 2])% dans% do.call (coller, df2 [1: 2]),]
Pardon. Mon vrai problème est que dans le csv original, j'ai des cas dans lesquels la ligne x a 4 40 comme valeurs dans les colonnes A et B respectivement et la ligne y a 40 4. Je suis désolé de ne pas l'afficher sous forme de tableau. Je ne sais pas comment faire ici. Ainsi, lorsque j'exécute cette ligne que vous avez suggérée, toutes les lignes de la table qui ont des valeurs de colonnes égales (juste inversées) sont supprimées. Je voulais juste supprimer les valeurs 40 4 sans supprimer les 4 40 celles. Désolé si l'explication n'est pas claire
expliquer mieux. J'ai créé une table (table 2) à partir de l'original (table1) et inversé les valeurs des colonnes A et B.Ainsi, lorsque j'exécute cette ligne que vous avez suggérée, non seulement les 40 4 sont supprimés, mais aussi les 4 40 . Je veux simplement supprimer les informations redondantes
@ApoloReis Pourquoi créez-vous alors une copie de la table originale? vous pouvez trier les deux colonnes de la table d'origine elle-même et en supprimer les valeurs dupliquées.
Voici une solution renvoyant les lignes de df1 et df2 , colonnes A et B , qui correspondent .
res <- apply(df2[1:2], 1, function(y){
apply(df1[1:2], 1, function(x) all(x == y))
})
which(res, arr.ind = TRUE)
# row col
#[1,] 4 2
w <- which(res, arr.ind = TRUE)
colnames(w) <- c('df1', 'df2')
w
# df1 df2
#[1,] 4 2
Une option avec data.table join
df1 <- data.frame("A" = c(1,2,3,4,5), "B" = c(10,20,30,40,50), "C" = c(6,7,8,9,11))
df2 <- data.frame("A" = c(10,4,30,20,50), "B" = c(1,40,3,7,5), "C" = c(12,13,14,15, 15))
library(data.table) setDT(df1)[!df2, on = .(A, B)] # A B C #1: 1 10 6 #2: 2 20 7 #3: 3 30 8 #4: 5 50 11
Votre syntaxe dans
if (for (j in 1: 5) {est fausse, dansif (expression)l'expression doit renvoyer une valeur logique (ou s'il y en a plusieurs , seul le premier est utilisé)