2012-05-09 20 views

Respuesta

16

esto funcionaría:

arr[do.call(order, lapply(1:NCOL(arr), function(i) arr[, i])), ] 

lo que está haciendo es:

arr[order(arr[, 1], arr[, 2], arr[ , 3]), ] 

excepción permite un número arbitrario de columnas en la matriz.

+0

¿No es el último pedido de columna redundante? Es decir. 1: (NCOL (arr) -1) haría lo mismo. – mdsumner

+1

No, no en todas las matrices, como 'arr = matrix (c (1, 1, 1, 1, 1, 3, 2, 1), nrow = 3)' –

+0

doh, gracias por eso :) – mdsumner

20

La función que está buscando es order (cómo llegué a esta conclusión - mi primer pensamiento fue "bien, la clasificación, ¿qué pasa con sort?" Intenté sort(arr) que parece que ordena arr como un vector en vez de fila. -wise. En cuanto a ?sort, veo en el "Vea también: order para ordenar o reordenar variables múltiples").

En cuanto a ?order, veo que order(x,y,z, ...) ordenará por x, rompiendo los lazos por y, rompiendo los lazos adicionales por z, y así sucesivamente. Genial, todo lo que tengo que hacer es pasar cada columna de arr a order para hacer esto. (Hay incluso un ejemplo de esto en la sección de Ejemplos de ?order):

order(arr[,1], arr[,2], arr[,3]) 
# gives 3 2 1: row 3 first, then row 2, then row 1. 
# Hence: 
arr[ order(arr[,1], arr[,2], arr[,3]), ] 
#  [,1] [,2] [,3] 
#[1,] 1 1 2 
#[2,] 1 2 3 
#[3,] 2 1 3 

Gran!


Pero es un poco molesto que tengo que escribir arr[,i] para cada columna en arr - ¿y si no sé cuántas columnas tiene de antemano?

Bueno, los ejemplos muestran cómo puedes hacer esto también: usando do.call. Básicamente, lo hace:

do.call(order, args) 

donde args es una lista de argumentos a order. Entonces, si puede hacer una lista de cada columna de arr, puede usar esto como args.

Una forma de hacer esto es es convertir arr en una trama de datos y luego en una lista - esto automágicamente poner una columna por cada elemento de la lista:

arr[ do.call(order, as.list(as.data.frame(arr))), ] 

El as.list(as.data.frame es un poco kludgy - Ciertamente hay otras maneras de crear una lista tal que list[[i]] es la iª columna de arr, pero esta es solo una.

+0

+1 para pasar el tiempo explicando en detalle! –

1

me escribió esta pequeña func que no orden decreciente, así cols permite elegir las columnas para ordenar y su orden

ord.mat = function(M, decr = F, cols = NULL){ 
    if(is.null(cols)) 
     cols = 1: ncol(M) 
    out = do.call("order", as.data.frame(M[,cols])) 
    if (decr) 
     out = rev(out) 
    return(M[out,]) 
} 
1

tuve un problema similar, y la solución parece ser simple y elegante:

t(apply(t(yourMatrix),2,sort)) 
Cuestiones relacionadas