varias para ordenar numericos nombres macro descendente datos como columnas automáticamente automaticamente ascendente apellidos alfanumericos alfabeticamente r performance data.table

para - Ordenar una tabla de datos rápido por orden ascendente/descendente



ordenar datos en excel ascendente y descendente (2)

Tengo una tabla de datos con aproximadamente 3 millones de filas y 40 columnas. Me gustaría ordenar esta tabla por orden descendente dentro de grupos como el siguiente código simulado de SQL:

sort by ascending Year, ascending MemberID, descending Month

¿Hay una forma equivalente en data.table para hacer esto? Hasta ahora tengo que dividirlo en 2 pasos:

setkey(X, Year, MemberID)

Esto es muy rápido y toma solo unos segundos.

X <- X[,.SD[order(-Month)],by=list(Year, MemberID)]

Este paso lleva mucho más tiempo (5 minutos).

Actualización: alguien hizo un comentario para hacer X <- X[sort(Year, MemberID, -Month)] y luego se eliminó. Este enfoque parece ser mucho más rápido:

user system elapsed 5.560 11.242 66.236

Mi enfoque: setkey () y luego ordenar (-Month)

user system elapsed 816.144 9.648 848.798

Mi pregunta es ahora: si quiero resumir por Año, MemberId y Mes después de la ordenación (Year, MemberID, Month), ¿data.table reconoce el orden de clasificación?

Actualización 2: a la respuesta a Matthew Dowle:

Después de configurar keykey con Year, MemberID y Month, todavía tengo varios registros por grupo. Lo que me gustaría es resumir para cada uno de los grupos. Lo que quise decir fue: si uso X [orden (Año, MemberID, Mes)], ¿la suma utiliza la función de búsqueda binaria de data.table:

monthly.X <- X[, lapply(.SD[], sum), by = list(Year, MemberID, Month)]

Actualización 3: Mateo D propuso varios enfoques. El tiempo de ejecución para el primer enfoque es más rápido que el enfoque de orden ():

user system elapsed 7.910 7.750 53.916

Matthew: lo que me sorprendió fue que convertir el signo del mes lleva la mayor parte del tiempo. Sin él, setkey está ardiendo rápidamente.


Actualización del 5 de junio de 2014:

La versión de desarrollo actual de data.table v1.9.3 tiene dos nuevas funciones implementadas, a saber: setorder y setorderv , que hace exactamente lo que usted necesita. Estas funciones reordenan el data.table por referencia con la opción de elegir orden ascendente o descendente en cada columna para ordenar. Echa un vistazo a ?setorder para más información.

Además, DT[order(.)] También está optimizado de manera predeterminada para usar el orden rápido interno de data.table lugar del base:::order . Esto, a diferencia del setorder , hará una copia completa de los datos, y por lo tanto es menos eficiente en memoria, pero seguirá siendo órdenes de magnitud más rápido que operando usando el orden de la base.

Puntos de referencia:

Aquí hay una ilustración de las diferencias de velocidad usando setorder , el orden rápido interno de data.table y con base:::order :

require(data.table) ## 1.9.3 set.seed(1L) DT <- data.table(Year = sample(1950:2000, 3e6, TRUE), memberID = sample(paste0("V", 1:1e4), 3e6, TRUE), month = sample(12, 3e6, TRUE)) ## using base:::order system.time(ans1 <- DT[base:::order(Year, memberID, -month)]) # user system elapsed # 76.909 0.262 81.266 ## optimised to use data.table''s fast order system.time(ans2 <- DT[order(Year, memberID, -month)]) # user system elapsed # 0.985 0.030 1.027 ## reorders by reference system.time(setorder(DT, Year, memberID, -month)) # user system elapsed # 0.585 0.013 0.600 ## or alternatively ## setorderv(DT, c("Year", "memberID", "month"), c(1,1,-1)) ## are they equal? identical(ans2, DT) # [1] TRUE identical(ans1, ans2) # [1] TRUE

En estos datos, los puntos de referencia indican que el orden de data.table es aproximadamente ~ 79x más rápido que el base:::order y el base:::order setorder es ~ 135x más rápido que el base:::order aquí.

data.table siempre ordena / ordena en C-locale. Si debe solicitar en otra configuración regional, solo entonces debe recurrir al uso de DT[base:::order(.)] .

Todas estas nuevas optimizaciones y funciones juntas constituyen FR # 2405 . También se ha agregado soporte para bit64 :: integer64 .

NOTA: Consulte el historial / revisiones para obtener respuestas y actualizaciones anteriores.


El comentario fue mío, así que voy a publicar la respuesta. Lo quité porque no pude probar si era equivalente a lo que ya tenías. Me alegra saber que es más rápido.

X <- X[order(Year, MemberID, -Month)]

El resumen no debe depender del orden de sus filas.