2010-05-12 23 views
9
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.datosseleccionar filas con mayor valor de la variable dentro de un grupo de r

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

+0

de fusión (a.3, id = c ("a.2")) -> h.2; cast (h.2, a.2 ~, max) Hace el truco en este ejemplo, pero la computadora se queda sin memoria cuando la aplico a mi conjunto de datos original. Entonces realmente no me ayudó mucho. – Misha

Respuesta

6
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,] 
+0

Eso fue mucho más simple, debo admitir ... Sin embargo, la lógica detrás de == b.2 está más allá de mí ... – Misha

+0

La ave genera un vector que solo contiene el máximo de b.2 por cada a.2. Por lo tanto, donde == b.2 establece un valor de verdad siempre que el marco de datos tenga filas. Está utilizando el vector lógico para seleccionar filas en el marco de datos. Si desea ver cómo funciona, agregue el resultado del comando ave a su marco de datos y mírelo, en comparación con la columna b.2 - a.3 $ b.max <- ave (b.2, a. 2, FUN = max) . Además, podría hacer que el sel sea variable y verlo en contexto con - a.3 $ sel <- a.3 $ b.2 == a.3 $ b.max – John

+0

Thx ... Agradezco sus esfuerzos. – Misha

1
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,] 

Esto hace el truco, aunque algo engorroso ... Pero me permite tomar las filas para los valores más grandes de groupwise. ¿Alguna otra idea?

1
> 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 
8
library(plyr) 
ddply(a.3, "a.2", subset, b.2 == max(b.2)) 
+0

Intenté usar la función ddply pero es dolorosamente lento. No tuve tiempo, pero duró un coffecup y un viaje al baño, mientras que la versión ave usó solo .2s en mi conjunto de datos original (210col * 16000rows). – Misha

+1

Eso se solucionará en la próxima versión.¡Pero no puede esperar obtener respuestas que funcionen con sus datos a menos que proporcione un ejemplo realista! – hadley

10

Los ddply y ave enfoques son a la vez bastante intensivos en recursos, creo. ave falla al quedarse sin memoria para mi problema actual (67,608 filas, con cuatro columnas que definen las claves únicas). tapply es una elección práctica, pero lo que generalmente necesito hacer es seleccionar todas las filas con el algo-valor de algún valor para cada clave única (generalmente definida por más de una columna). La mejor solución que he encontrado es hacer una ordenación y luego usar la negación de duplicated para seleccionar solo la primera fila para cada clave única. Para el ejemplo simple 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 llaves de múltiples columnas, pero order manejará un montón de cosas para ordenar y duplicated funciona en marcos de datos, por lo que es posible continuar utilizando este enfoque.

+0

Este fue el más fácil de usar y funciona muy bien en varias columnas; todo lo que necesita hacer es usar 'cbind' dentro de' duplicated'. –

0
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 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 
Cuestiones relacionadas