9
votes

Dans ID, vérifiez les matchs / Différences

J'ai un grand jeu de données, plus de 1,5 million de lignes, de 600 000 sujets uniques, un certain nombre de sujets ont donc plusieurs rangées. J'essaie de trouver les cas où l'un des sujets a un dob saisi de manière incorrecte.

test <- data.frame(
    ID=c(rep(1,3),rep(2,4),rep(3,2)),
    DOB = c(rep("2000-03-01",3), "2000-05-06", "2002-05-06",
     "2000-05-06", "2000-05-06", "2004-04-06", "2004-04-06")
)

> test
  ID        DOB
1  1 2000-03-01
2  1 2000-03-01
3  1 2000-03-01
4  2 2000-05-06
5  2 2002-05-06
6  2 2000-05-06
7  2 2000-05-06
8  3 2004-04-06
9  3 2004-04-06

r

0 commentaires

4 Réponses :


2
votes
DOBError <- function(data){

     count <- unlist(lapply(split(test, test$ID), 
        function(x)length(unique(x$DOB))))

     return(names(count)[count > 1])

}


DOBError(data)

[1] "2"

1 commentaires

Merci, n'avait pas vu illist ou scindé avant, mais la longueur (unique ()) était ce que je pensais aussi.



5
votes

une approche utilisant plyr : xxx

et si la base r est votre chose, en utilisant agrégat () < Pré> xxx


3 commentaires

Bon merci! Une autre nouvelle fonction que je ne connaissais pas. Par curiosité, connaissez-vous un moyen d'obtenir cela pour traiter un vecteur de la même longueur que nrow (test)? Comme dans 1 1 1 2 2 2 2 1 1? Il suffit de penser à l'application de ceci à d'autres fonctions et où vous pourriez aimer conserver les données dans ce format longitudinal.


@nzcoops - dans le cas de la solution Plyr , remplacez résumée avec transformer . Il ne cline pas immédiatement dans ma tête comment ajuster la solution agrégate , mais je vais mettre à jour cette réponse quand je le fais.


Voici un Agrégation Possibilité: Agrégation (Test $ DOB, by = liste (test $ ID), fonction fonction (x) (unique (x))> 1)



6
votes

Utilisation des fonctions de base, la solution la plus rapide serait quelque chose du genre:

n <- 1000
system.time(replicate(n,{
  x <- unique(test[c("ID","DOB")])
  x$ID[duplicated(x$ID)]
 }))
   user  system elapsed 
   0.70    0.00    0.71 

system.time(replicate(n,{
  DOBError(data)
}))
   user  system elapsed 
   1.69    0.00    1.69 

system.time(replicate(n,{
  zzz <- aggregate(DOB ~ ID, data = test, FUN = function(x) length(unique(x)))
  zzz[zzz$DOB > 1 ,]
}))
   user  system elapsed 
   4.23    0.02    4.27 

system.time(replicate(n,{
   zz <- ddply(test, "ID", summarise, dups = length(unique(DOB)))
   zz[zz$dups > 1 ,]
}))
   user  system elapsed 
   6.63    0.01    6.64 


3 commentaires

Intéressant. Merci Joris. Je dois attendre 8 heures pour poster une réponse, mais j'ai aussi fait des tests de vitesse sur 100 000 rangées de mes données réelles. Curieusement, j'ai eu la fonction d'agrégation qui fonctionne sensiblement plus rapidement que la fonction Doberror.


@NZCOOPS: Cela dépend de la taille du Dataframe. Parfois, le code peut être plus rapide lors de la réplication de 1000 fois sur de petites données, mais plus lentement lorsqu'il est effectué sur un deataframe qui est 1000 fois plus grand.


ahhhh ddlly () est un cochon en comparaison! Je suppose que c'est le prix que vous payez pour la commodité (parfois). Je me demande quel effet bascule le commutateur .paralell peut avoir. +1 pour les comparaisons de temps.



3
votes

Avec un tel volume, je propose une autre solution, sur la base de comparaisons et utilisez la puissance des opérations de vecteur dans R: xxx

pour test TIMING de données est similaire à Joris Idea , mais pour de grandes données: xxx


1 commentaires

Joli! J'ai dû penser un peu ce qui se passait, mais une belle solution.