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
4 Réponses :
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"
Merci, n'avait pas vu illist ou scindé avant, mais la longueur (unique ()) était ce que je pensais aussi.
une approche utilisant et si la base r est votre chose, en utilisant plyr code>:
agrégat () p> p> < Pré> xxx pré> p>
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 code>, remplacez
résumée code> avec
transformer code>. Il ne cline pas immédiatement dans ma tête comment ajuster la solution code> agrégate code>, mais je vais mettre à jour cette réponse quand je le fais.
Voici un Agrégation Code> Possibilité:
Agrégation (Test $ DOB, by = liste (test $ ID), fonction fonction (x) (unique (x))> 1) code>
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
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 () code> 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 code> peut avoir. +1 pour les comparaisons de temps.
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: pour test code> TIMING de données est similaire à Joris Idea , mais pour de grandes données: P>
Joli! J'ai dû penser un peu ce qui se passait, mais une belle solution.