sélectionner des lignes avec la plus grande valeur de la variable au sein d'un groupe en r

StackOverflow https://stackoverflow.com/questions/2822156

  •  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?

Était-ce utile?

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top