2012-05-09 14 views

Odpowiedz

16

to będzie działać:

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

co robi jest:

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

wyjątkiem pozwala na dowolną liczbę kolumn w macierzy.

+0

Czy ostatnia kolejność kolumn nie jest nadmiarowa? To znaczy. 1: (NCOL (arr) -1) zrobiłby to samo. – mdsumner

+1

Nie, nie we wszystkich macierzach, takich jak 'arr = matrix (c (1, 1, 1, 1, 1, 1, 3, 2, 1), nrow = 3)' –

+0

doh, fajne dzięki za to :) – mdsumner

20

Funkcja jesteś po to order (jak przyjechałem do tego wniosku - moja pierwsza myśl była „dobrze, sortowania, co sort?” Tried sort(arr) który wygląda jak sortuje arr jako wektor zamiast rzędu. W przypadku patrzenia na ?sort widzę w "Zobacz też: order do sortowania lub zmiany kolejności wielu zmiennych.").

Patrząc na ?order, widzę, że order(x,y,z, ...) nakaże przez x, zerwania więzi przez y, łamiąc kolejne więzi przez z, i tak dalej. Świetne - wszystko, co muszę zrobić, to przejść w każdej kolumnie od arr do order, aby to zrobić. (Nie ma jeszcze przykładem na to w rozdziale Przykłady ?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 

Great!


Ale jest to trochę irytujące, że muszę napisać arr[,i] dla każda kolumna w arr - co, jeśli nie wiem, ile kolumn ma z góry?

Przykłady pokazują, jak możesz to zrobić: używając do.call. Zasadniczo, można zrobić:

do.call(order, args) 

gdzie args jest lista argumentów do order. Jeśli więc możesz utworzyć listę z każdej kolumny arr, możesz użyć tego jako args.

Jednym ze sposobów zrobienia tego jest, by konwersja arr do ramki danych, a następnie umieszczane na liście - to automagicznie umieścić jedną kolumnę na element listy:

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

as.list(as.data.frame jest nieco kludgy - na pewno istnieją inne sposoby tworzenia listy, w której list[[i]] jest kolumną i th z arr, ale jest to tylko jedna.

+0

+1 za czas spędzony na wyjaśnianiu szczegółów! –

1

pisałem ten mały func że ma odwrotną kolejność oraz cols pozwala wybrać, które kolumny na zamówienie i ich kolejność

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

Miałem podobny problem, a rozwiązanie wydaje się być prosty i elegancki:

Powiązane problemy