seleccionar filas con mayor valor de la variable dentro de un grupo en el r
-
26-09-2019 - |
Pregunta
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,]
devuelve el índice de la lista, no el índice para toda la hoja.de.datos
Estoy tratando de devolver el valor más grande de b.2
para cada subgrupo de a.2
. ¿Cómo puedo hacer esto de manera eficiente?
Solución
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 respuesta de Jonathan Chang le consigue lo que usted pidió explícitamente, pero supongo que desea que la fila actual de la trama de datos.
sel <- ave(b.2, a.2, FUN = max) == b.2
a.3[sel,]
Otros consejos
Los enfoques ddply
y ave
son ambos bastante intensivos en recursos, creo. ave
falla de funcionamiento de la memoria de mi problema actual (67,608 filas, con cuatro columnas que define las claves únicas). tapply
es una opción muy útil, pero lo que normalmente hay que hacer es seleccionar todas las filas enteras y con algo-est algún valor para cada clave única (por lo general definida por más de una columna). La mejor solución que he encontrado es hacer una especie y luego usar negación de duplicated
para seleccionar sólo la primera fila para cada clave única. Por el simple ejemplo aquí:
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),]
creo que las mejoras de rendimiento más ave
o ddply
, al menos, son sustanciales. Es un poco más complicado para las llaves de varias columnas, pero order
manejará un montón de cosas para ordenar y obras duplicated
en tramas de datos, por lo que es posible continuar utilizando este enfoque.
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,]
Este es el truco, aunque algo complicado ... Pero me permite agarrar las filas de los valores más grandes de GroupWise. Alguna otra idea?
> 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)
Con aggregate
, se puede obtener el máximo para cada grupo en una sola línea:
aggregate(a.3, by = list(a.3$a.2), FUN = max)
Esto produce el siguiente resultado:
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