sélectionner des lignes avec la plus grande valeur de la variable au sein d'un groupe en r
-
26-09-2019 - |
Question
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
r<-sapply(split(a.3,a.2),function(x) which.max(x$b.2))
a.3[r,]
renvoie l'index de la liste, et non l'indice pour l'ensemble data.frame
Im essayant de revenir la plus grande valeur de b.2
pour chaque sous-groupe de a.2
. Comment puis-je faire efficacement?
La solution
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
La réponse de Jonathan Chang vous obtient ce que vous avez demandé explicitement, mais je devine que vous voulez la ligne réelle de la trame de données.
sel <- ave(b.2, a.2, FUN = max) == b.2
a.3[sel,]
Autres conseils
Les approches ddply
et ave
sont tous deux assez de ressources, je pense. ave
échoue en exécutant de mémoire pour mon problème actuel (67,608 lignes, avec quatre colonnes définissant les clés uniques). tapply
est un choix pratique, mais ce que je dois en général à faire est de sélectionner toutes les lignes entières avec la valeur un peu quelque chose-est pour chaque clé unique (généralement définie par plus d'une colonne). La meilleure solution que j'ai trouvé est de faire une sorte puis utilisez la négation de duplicated
pour sélectionner uniquement la première ligne pour chaque clé unique. Pour l'exemple simple ici:
a <- sample(1:10,100,replace=T)
b <- sample(1:100,100,replace=T)
f <- data.frame(a, b)
sorted <- f[order(f$a, -f$b),]
highs <- sorted[!duplicated(sorted$a),]
Je pense que les gains de performance sur ave
ou ddply
, au moins, sont considérables. Il est un peu plus compliqué pour les clés à plusieurs colonnes, mais order
va gérer tout un tas de choses à trier et travaux de duplicated
sur des trames de données, il est donc possible de continuer à utiliser cette approche.
library(plyr)
ddply(a.3, "a.2", subset, b.2 == max(b.2))
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
m<-split(a.3,a.2)
u<-function(x){
a<-rownames(x)
b<-which.max(x[,2])
as.numeric(a[b])
}
r<-sapply(m,FUN=function(x) u(x))
a.3[r,]
fait le tour, mais un peu lourd ... Mais cela me permet de saisir les lignes pour les plus grandes valeurs Groupwise. D'autres idées?
> a.2<-sample(1:10,100,replace=T)
> b.2<-sample(1:100,100,replace=T)
> tapply(b.2, a.2, max)
1 2 3 4 5 6 7 8 9 10
99 92 96 97 98 99 94 98 98 96
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
Avec aggregate
, vous pouvez obtenir le maximum pour chaque groupe en une ligne:
aggregate(a.3, by = list(a.3$a.2), FUN = max)
Ceci produit la sortie suivante:
Group.1 a.2 b.2
1 1 1 96
2 2 2 82
...
8 8 8 85
9 9 9 93
10 10 10 97