2012-10-09 24 views
8

tengo una siguiente trama de datosCómo pedir mi trama de datos lexicographicaly

a = data.frame(a=c(1,2,3,4,5,6,7),b=c(1,2,3,10,12,21,4),c=c(1,2,10,11,"X","Y",3)) 
> a 
    a b c 
1 1 1 1 
2 2 2 2 
3 3 3 10 
4 4 10 11 
5 5 12 X 
6 6 21 Y 
7 7 4 3 

que desea ordenar trama de datos todo en orden lexicográfico, por lo que la salida (por ejemplo, la columna "c") debe ser como

> a[,"c"] 
[1] 1 2 3 10 11 X Y 

he intentado y estoy Consiguiendo respuesta diferente

indata <- a[do.call(order,a[,c("c","a","b")]),] 
> indata[,"c"] 
[1] 1 10 11 2 3 X Y 
Levels: 1 10 11 2 3 X Y 

probé gtools, Mixedorder paquete de una nd funcionó bien en una columna:

> a[mixedorder(a$c),] 
    a b c 
1 1 1 1 
2 2 2 2 
3 3 3 10 
4 4 10 11 
5 5 12 X 
6 6 21 Y 
7 7 4 3 

pero no funciona si incluyo varias columnas:

> a[with(a,order(mixedorder(c),mixedorder(b),mixedorder(a))),] 
    a b c 
1 1 1 1 
2 2 2 2 
4 4 10 11 
5 5 12 X 
6 6 21 Y 
7 7 4 3 
3 3 3 10 

aunque yo estoy esperando:

a b c 
1 1 1 1 
2 2 2 2 
4 7 4 3 
5 3 3 10 
6 4 10 11 
7 5 12 X 
3 6 21 Y 
+0

Tendrás que ser más claro. ¿Desea ordenar simplemente la columna 'c', o el marco de datos completo con respecto a las columnas' c'? – joran

+0

Quiero ordenar todo el marco de datos con respecto a c. Di una [, "c"] para una fácil comprensión – user1631306

Respuesta

7

Una opción es utilizar mixedorder() del paquete gtools.

library(gtools) 
a[mixedorder(a$c),] 
# a b c 
# 1 1 1 1 
# 2 2 2 2 
# 7 7 4 3 
# 3 3 3 10 
# 4 4 10 11 
# 5 5 12 X 
# 6 6 21 Y 
+1

¿Cómo usaría varias columnas juntas para clasificar (primero c, luego b y luego a)? – user1631306

+1

@ user1631306 Pruebe 'arreglar' en el paquete ** plyr **. – joran

+2

@ user1631306 - En ese caso, podría hacer esto: 'a [con (a, orden (mixedorder (c), b, a)),]'. –

4

pegarse en la base que podría hacer una función de sí mismo:

a = data.frame(a=c(1,2,3,4,5,6,7),b=c(1,2,3,10,12,21,4),c=c(1,2,10,11,"X","Y",3)) 

SORTER_DEVICE <- function(x) { 
    c(sort(as.numeric(na.omit(gsub("[a-zA-Z]", NA, x)))), 
     sort(na.omit(gsub("[0-9]", NA, x)))) 
} 
data.frame(apply(a, 2, SORTER_DEVICE)) 
1

Desafortunadamente mixedsort no (todavía) no son compatibles con múltiples columna de clasificación. Por lo tanto, es necesario implementar por sí mismo, por ejemplo, así:

a[order(sub("[0-9]+", "", a$c), 
     as.numeric(sub("[[:alpha:]]*([[:digit:]]*)", '\\1', a$c)), 
     as.numeric(a$b), 
     as.numeric(a$a)), ] 

Esta primera, de forma alfanumérica ordena hoja.de.datos utilizando un $ c, y para situaciones de unión (que en realidad no existe en su hoja.de.datos ' a '), usa $ b y a $ a.

de salida es:

a b c 
1 1 1 1 
2 2 2 2 
7 7 4 3 
3 3 3 10 
4 4 10 11 
5 5 12 X 
6 6 21 Y 

PD: Esto fue escrito por David Winsemius en this post como una respuesta a una pregunta similar.