2017-05-08 1 views
2

J'ai deux grandes bases de données dans lesquelles une table contient moins d'observations. Anti-join de dplyr fonctionne parfaitement et rapidement, mais je garderais les noms de lignes d'origine si possible. Toute fonction/package qui permet cela avec la vitesse d'anti_join? Ma solution actuelleRecherche de numéros de ligne qui se trouvent dans la table mais pas dans la seconde

library(magrittr) 
library(dplyr) 

iris 
iris2 <- iris[-c(3, 9, 30, 40), ] 

iris <- iris %>% mutate(rown = 1:n()) 

anti_join(iris, iris2) %>% set_rownames(.$rown) %>% select(-rown) 

EDIT: Vous cherchez une solution où je n'ai pas besoin d'ajouter rownumber.

+1

Il y a 'row_number()' en dplyr-à-dire au lieu de '1: n()' , vous pouvez utiliser 'mutate (rown = row_number())' – akrun

+1

Il suffit de le garder comme une colonne, ce qui à long terme sera plus utile à moins que vous ne fassiez beaucoup avec des matrices: 'library (tidyverse); iris%>% rownames_to_column ('i')%>% anti_join (iris2) ' – alistaire

+0

@MLEN - il semble que vous ayez changé la question en une question différente: en essayant maintenant d'éviter que les rownumbers ne s'impliquent. Tout le monde a déjà répondu à la vieille question et ne peut pas effacer tout ce qu'ils ont soumis. Si vous avez trouvé leur travail utile pour répondre à votre question initiale, pouvez-vous choisir une réponse à cette question? Ensuite, si vous souhaitez poser une nouvelle question, veuillez renvoyer votre nouvelle question sous la forme d'une nouvelle question. De cette façon, vous serez en mesure d'obtenir des réponses à votre nouvelle question. –

Répondre

1

qu'en est-il de R simple?

iris$rows<-seq(1,dim(iris)[1],1) 
iris2 <- iris[-c(3, 9, 30, 40), ] 
iris[which(!(iris$rows %in% iris2$rows)),] 

Comparaison temps

iris <- iris %>% mutate(rown = 1:n()) 
iris$rows<-seq(1,dim(iris)[1],1) 
iris2 <- iris[-c(3, 9, 30, 40), ] 


    f=function(){ 
     anti_join(iris, iris2) %>% set_rownames(.$rown) %>% select(-rown) 
    } 


f2=function(){ 
    iris[which(!(iris$rows %in% iris2$rows)),] 
} 

    microbenchmark(f(),f2()) 

expr  min  lq  mean median  uq  max neval 
    f() 1531.523 1832.0710 2384.1375 2407.061 2828.096 4084.061 100 
f2() 104.869 168.0125 238.7027 235.396 290.284 513.185 100 

sans utiliser les lignes numéro

mtcars 
mtcars2<-mtcars[-c(3,9,40),] 
mtcars[which(!row.names(mtcars) %in% row.names(mtcars2)),] 

Hope it helps

+0

Cela ne fonctionnera pas pour mes données réelles car il n'y a pas de "rown" correspondant. – MLEN

+0

Désolé, je ne comprends pas pourquoi cela ne devrait pas fonctionner dans votre cas, il vous suffit d'adapter cette approche à vos données, même si vous avez un ID de personnage. –

+0

Vous pouvez démarrer l'iris et créer un numéro de ligne, puis le diviser en 2 images. Je commence avec 2 images pour mes données en particulier sans aucune "ligne" – MLEN

1

dplyr setdiff de

setdiff(iris, iris2) 

Il est un peu plus agile qu'un anti_join car il est de l'ensemble des opérations traditionnelles ilk et a besoin de colonnes correspondantes, mais c'est un bon cas d'utilisation.

L'exemple complet:

iris <- 
    iris %>% 
    mutate(rown = 1:n()) 

iris2 <- 
    iris[-c(3, 9, 30, 40), ] 

setdiff(iris, iris2) 
> setdiff(iris, iris2) 
    Sepal.Length Sepal.Width Petal.Length Petal.Width Species rown 
1   4.7   3.2   1.3   0.2 setosa 3 
2   4.4   2.9   1.4   0.2 setosa 9 
3   4.7   3.2   1.6   0.2 setosa 30 
4   5.1   3.4   1.5   0.2 setosa 40 

Cependant, j'exécutiez la solution base de R de Federico, aussi, et il se trouve que le which n'est pas le seul contributeur au temps significatif réduction. L'utilisation de la méthode R de base pour générer une colonne rownumbers au lieu d'une mutation est ce qui réduit le temps de traitement. Dans tous les cas, si vous déposez simplement un iris$rown<-seq(1,dim(iris)[1],1) dans votre code d'origine, et ne dérangez pas la renumérotation de vos lignes, vous constaterez une baisse importante de votre temps de traitement. which gagne encore à peine par un moustache, bien que je trouve personnellement que le sacrifice de microsecondes ici vaut bien la facilité et la lisibilité de setdiff(bigTbl, smallTbl).

L'ensemble complet d'essais est allé comme ceci:

antjn_set_rwnms=function(){ 
    iris <- iris %>% mutate(rown = 1:n()) 
    iris2 <- iris [-c(3, 9, 30, 40), ] 
    anti_join(iris , iris2) %>% set_rownames(.$rown) %>% select(-rown) 
} 
antjn_rwnum=function(){ 
    iris <- iris %>% mutate(rown = row_number()) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    anti_join(iris, iris2) 
} 
antjn_1n=function(){ 
    iris <- iris %>% mutate(rown = 1:n()) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    anti_join(iris, iris2) 
} 
stdff_seq=function(){ 
    iris$rown<-seq(1,dim(iris)[1],1) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    setdiff(iris, iris2) 
} 
stdff_rwnum=function(){ 
    iris <- iris %>% mutate(rown = row_number()) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    setdiff(iris, iris2) 
} 
stdff_1n=function(){ 
    iris <- iris %>% mutate(rown = 1:n()) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    setdiff(iris, iris2) 
} 
whch_1n=function(){ 
    iris <- iris %>% mutate(rown = 1:n()) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    iris[which(!(iris$rown %in% iris2$rown)),] 
} 
whch_seq=function(){ 
    iris$rown<-seq(1,dim(iris)[1],1) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    iris[which(!(iris$rown %in% iris2$rown)),] 
} 
antjn_seq=function(){ 
    iris$rown<-seq(1,dim(iris)[1],1) 
    iris2 <- iris[-c(3, 9, 30, 40), ] 
    anti_join(iris, iris2) 
} 


microbenchmark(
       antjn_set_rwnms(), 
       antjn_rwnum(), 
       antjn_1n(), 
       stdff_1n(), 
       stdff_rwnum(), 
       whch_1n(), 
       antjn_seq(), 
       stdff_seq(), 
       whch_seq(), 
       times = 10000L) 

Cédant les résultats suivants:

Unit: microseconds 
       expr  min  lq  mean median  uq  max neval 
antjn_set_rwnms() 2858.014 3343.828 4268.2085 3891.226 4890.2260 97763.88 10000 
    antjn_rwnum() 2273.410 2612.540 3401.6724 3043.615 3897.2130 89484.50 10000 
     antjn_1n() 2278.114 2617.886 3371.6463 3048.748 3899.7790 75887.23 10000 
     stdff_1n() 1390.305 1591.302 2117.1687 1852.385 2465.6405 88135.68 10000 
    stdff_rwnum() 1383.034 1581.466 2073.9099 1811.329 2421.8065 59467.88 10000 
     whch_1n() 1347.539 1550.247 2083.1022 1810.261 2405.1275 76800.70 10000 
     antjn_seq() 1168.779 1406.555 1847.2465 1621.024 2112.1845 87611.37 10000 
     stdff_seq() 336.564 421.668 567.4554 480.684 660.2985 64252.05 10000 
     whch_seq() 285.246 382.323 514.1107 437.063 595.7225 16619.50 10000