Предположим, что
arr = 2 1 3
1 2 3
1 1 2
Как я могу отсортировать это в ниже?
arr = 1 1 2
1 2 3
2 1 3
То есть сначала по столбцу один, затем по столбцу два и т.д.
Предположим, что
arr = 2 1 3
1 2 3
1 1 2
Как я могу отсортировать это в ниже?
arr = 1 1 2
1 2 3
2 1 3
То есть сначала по столбцу один, затем по столбцу два и т.д.
Это будет работать:
arr[do.call(order, lapply(1:NCOL(arr), function(i) arr[, i])), ]
Что он делает:
arr[order(arr[, 1], arr[, 2], arr[ , 3]), ]
за исключением того, что позволяет произвольное количество столбцов в матрице.
Функция, за которой вы находитесь, - order
(как я пришел к такому выводу - моя первая мысль была "хорошо, сортировка, а что насчет sort
?". Пробовал sort(arr)
, который выглядит как сортирует arr
в качестве вектора вместо строки. Посмотрев ?sort
, я вижу в разделе "См. также: order
для сортировки или переупорядочения переменных несколько.)).
Глядя на ?order
, я вижу, что order(x,y,z, ...)
будет упорядочиваться на x
, разбивая связи на y
, разбивая дальнейшие связи на z
и т.д. Отлично - все, что мне нужно сделать, это передать в каждом столбце от arr
до order
для этого. (Для примера есть пример в разделе примеров ?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
Отлично!
Но это немного раздражает, что я должен написать arr[,i]
для каждого столбца в arr
- что, если я не знаю, сколько столбцов оно имеет заранее?
Ну, примеры показывают, как вы можете это сделать: используя do.call
. В основном, вы делаете:
do.call( order, args )
где args
- список аргументов в order
. Поэтому, если вы можете составить список из каждого столбца arr
, вы можете использовать его как args
.
Один из способов сделать это - преобразовать arr
в кадр данных, а затем в список - это автоматически поместит по одному столбцу на элемент списка:
arr[ do.call( order, as.list(as.data.frame(arr)) ), ]
as.list(as.data.frame
бит kludgy - есть, конечно, другие способы создания списка, чтобы list[[i]]
был i
-й столбец arr
, но это всего лишь один.
Я написал эту небольшую функциональность, которая также уменьшает порядок cols позволяет выбирать столбцы для заказа и порядок
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,])
}
У меня была аналогичная проблема, и решение кажется простым и элегантным:
t(apply(t(yourMatrix),2,sort))