Ordenar filas en data.table en orden decreciente en la clave de cadena `order (-x, v)` da error en data.table 1.9.4 o anterior

125

Digamos que tengo lo siguiente data.tableen R:

  library(data.table)
  DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)

Quiero ordenarlo por dos columnas (digamos columnas xy v). Usé esto:

 DT[order(x,v)] # sorts first by x then by v (both in ascending order)

Pero ahora, quiero ordenarlo por x(en orden decreciente) y tener el siguiente código:

  DT[order(-x)] #Error in -x : invalid argument to unary operator

Por lo tanto, creo que este error se debe al hecho de que class(DT$x)=character. ¿Podría darme alguna sugerencia para resolver este problema?

Sé que puedo usar DT[order(x,decreasing=TRUE)], pero quiero saber la sintaxis para ordenar por varias columnas usando ambas formas (algunas decrecientes, otras crecientes) al mismo tiempo.

Tenga en cuenta que si usa DT[order(-y,v)]el resultado está bien, pero si lo usa, DT[order(-x,v)]hay un error. Entonces, mi pregunta es: ¿cómo resolver este error?

nhern121
fuente
66
Pregunta interesante, pero si está trabajando con grandes conjuntos de datos, probablemente debería configurar las claves para sus data.tables. Las teclas ordenan sus datos en un orden que maximiza la indexación, subconjunto, agregación por grupos, etc., que pueden no ser su formato preferido para imprimir los datos, pero a menudo es un pequeño precio a pagar por la velocidad que obtendrá. .
Josh O'Brien
Sin embargo, me parece que DT[order(-x)]no es una declaración equivalente a setorder(DT, -x)porque setorder()realmente actúa DTmientras que el otro no. Las declaraciones equivalentes serían DT <- DT [order (-x)] setorder (DT, -x) Soy muy nuevo en R, así que corríjalo si me equivoco.
jeromeResearch
@jerome Tienes razón. Pankil no dijo que fueran equivalentes, así que supongo que está bien como está.
Frank
1
Estoy de acuerdo con @smci en que una edición de título tiene sentido aquí, aunque lo cambiaría para indicar que esta pregunta ya no es relevante, por ejemplo, agregando "en data.table 1.9.4 o anterior" al título para que la gente no lo haga. continuar aterrizando aquí desde google esperando algo más. Hice esto con una de mis preguntas stackoverflow.com/questions/30035939/…
Frank
1
Nestorggh, no revierta el nuevo título a menos que pueda mejorarlo. "ordenar filas en data.table" no dijo casi nada, esa funcionalidad básica estaba ahí para los yonks. El título debe mencionar su problema real (varias claves donde una es el orden de descifrado). También es importante que se tratara de un problema conocido en 1.9.4 y anteriores y que ya no es un problema.
smci

Respuestas:

144

Actualizar

data.table v1.9.6 + ahora admite el intento original de OP y la siguiente respuesta ya no es necesaria.


Puedes usar DT[order(-rank(x), y)].

   x y v
1: c 1 7
2: c 3 8
3: c 6 9
4: b 1 1
5: b 3 2
6: b 6 3
7: a 1 4
8: a 3 5
9: a 6 6
Matthew Plourde
fuente
1
Como señaló @PankilShah a continuación, esto se ha solucionado durante algún tiempo y el enfoque original de OP ahora funciona como se esperaba. No pude encontrar el commit ya que se solucionó en el nivel C y no sé qué buscar.
MichaelChirico
1
Genial, gracias. Parece poco probable que alguien termine aquí ... pero, por otro lado, yo mismo terminé buscando en Google algo vagamente relacionado.
MichaelChirico
@MichaelChirico en realidad, obtengo votos de forma rutinaria por esta respuesta, así que me alegra que lo hayas señalado. No soy realmente un usuario de data.table y no he estado al día con su desarrollo.
Matthew Plourde
Es muy útil para indicar el número de la versión actual (1.9.6?), Así que no tenemos que ir a cazar en los archivos de NEWS.md .
smci
23

Solo puede usar -en las entradas numéricas, por lo que puede usar disminuir y negar las que desee en orden creciente:

DT[order(x,-v,decreasing=TRUE),]
      x y v
 [1,] c 1 7
 [2,] c 3 8
 [3,] c 6 9
 [4,] b 1 1
 [5,] b 3 2
 [6,] b 6 3
 [7,] a 1 4
 [8,] a 3 5
 [9,] a 6 6
James
fuente
3
Me gusta de esta manera, a menos que tenga dos charactercolumnas y desee ordenar una creciente y otra decreciente.
Matthew Plourde
1
@mplourde Creo que puede combinar su solución con esta para abordar el problema que ha planteado. Por ejemplo, puede poner: DT[order(x,-rank(w),decreasing=TRUE)]dado eso xy wambas son columnas de caracteres. ¡Gracias!
nhern121
17

DT[order(-x)]Funciona como se esperaba. Tengo data.table versión 1.9.4. Tal vez esto se solucionó en una versión reciente.
Además, sugiero la setorder(DT, -x)sintaxis de acuerdo con los comandos set * como setnames,setkey

Pankil Shah
fuente