Compreender a função order ()

88

Estou tentando entender como order()funciona a função. Tive a impressão de que ele retornou uma permutação de índices que, quando classificados, classificariam o vetor original.

Por exemplo,

> a <- c(45,50,10,96)
> order(a)
[1] 3 1 2 4

Eu esperava que isso retornasse c(2, 3, 1, 4), uma vez que a lista classificada seria 10 45 50 96.

Alguém pode me ajudar a entender o valor de retorno dessa função?

Jeffshantz
fonte

Respostas:

100

Isso parece explicar isso.

A definição de orderé que a[order(a)]está em ordem crescente. Isso funciona com o seu exemplo, onde a ordem correta é o quarto, segundo, primeiro e depois o terceiro elemento.

Você pode estar procurando rank, que retorna a classificação dos elementos e,
R> a <- c(4.1, 3.2, 6.1, 3.1)
R> order(a)
[1] 4 2 1 3
R> rank(a)
[1] 3 2 4 1
portanto, rankinforma em que ordem os números estão e ordercomo obtê-los em ordem crescente.

plot(a, rank(a)/length(a))dará um gráfico do CDF. Para ver por que orderé útil, no entanto, tente o plot(a, rank(a)/length(a),type="S") que dá uma bagunça, porque os dados não estão em ordem crescente

Se você fez
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
ou simplesmente
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
obtém um gráfico de linha do CDF.

Aposto que você está pensando em classificação.

duffymo
fonte
8
Ahh .. eu vejo agora. order () retorna os índices do vetor em ordem classificada. Maravilhoso, muito obrigado.
jeffshantz
order(a, decreasing = T)e rank(a)retornará uma resposta equivalente.
omar
Estou tendo problemas com o pedido. a<-c(4,2,1,80,13)Então order(a)deveria ser 3 4 5 1 2, mas estranhamente estou recebendo3 2 1 5 4
Shoham Debnath
1
@duffymo uma ajudinha aqui seria muito apreciada. Quando é ranke ordermesmo?
Shoham Debnath de
Na verdade, order(order(a))retornará o mesmo como rank(a) se não houvesse empate. Se houver, ele retornará o mesmo que rank(a, ties.method="first").
jac
33

Para classificar um vetor 1D ou uma única coluna de dados, basta chamar a função de classificação e passar sua sequência.

Por outro lado, a fim função é necessária para classificar os dados de dois dados dimensionais - isto é, várias colunas de dados recolhidos em uma matriz ou trama de dados.

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

Aqui está um trecho de dados para tentativas de field goal na temporada de 2008 da NFL, um dataframe que chamei de 'fg'. suponha que esses 10 pontos de dados representem todos os gols tentados em 2008; além disso, suponha que você queira saber a distância do field goal mais longo tentado naquele ano, quem chutou e se foi bom ou não; você também deseja saber o segundo mais longo, bem como o terceiro mais longo, etc .; e, finalmente, você deseja a menor tentativa de gol de campo.

Bem, você poderia apenas fazer isso:

sort(fg$Dist, decreasing=T)

que retorna: 50 48 43 37 34 32 26 25 25 20

Isso está correto, mas não é muito útil - ele nos diz a distância da tentativa de field goal mais longa, a segunda mais longa, ... bem como a mais curta; no entanto, mas isso é tudo que sabemos - por exemplo, não sabemos quem foi o chutador, se a tentativa foi bem-sucedida, etc. Claro, precisamos de todo o dataframe classificado na coluna "Dist" (dito de outra forma, nós deseja classificar todas as linhas de dados no único atributo Dist . que ficariam assim:

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

Isso é o que a ordem faz. É 'classificar' para dados bidimensionais; dito de outra forma, ele retorna um índice inteiro 1D composto de números de linha, de modo que classificar as linhas de acordo com aquele vetor, daria a você uma classificação orientada por linha correta na coluna, Dist

É assim que funciona. Acima, classificar foi usado para classificar a coluna Dist; para classificar todo o dataframe na coluna Dist, usamos 'ordenar' exatamente da mesma forma que 'classificar' é usado acima :

ndx = order(fg$Dist, decreasing=T)

(eu geralmente vinculo a matriz retornada de 'ordem' à variável 'ndx', que significa 'índice', porque vou usá-la como uma matriz de índice para classificar.)

essa foi a etapa 1, aqui está a etapa 2:

'ndx', o que é retornado por 'sort' é então usado como uma matriz de índice para reordenar o dataframe, 'fg':

fg_sorted = fg[ndx,]

fg_sorted é o dataframe reordenado imediatamente acima.

Em suma, 'sort' é usado para criar um array de índice (que especifica a ordem de classificação da coluna que você deseja classificar), que então é usado como um array de índice para reordenar o dataframe (ou matriz).

doug
fonte
2
-1: a ordem faz muito sentido para um vetor. A propriedade básica da ordem - que uma [ordem (a)] é classificada - não é claramente declarada.
Jyotirmoy Bhattacharya
2
Errado. você precisa olhar novamente - a 'propriedade básica' é realmente mostrada muito claramente nas duas linhas de código (com fundo cinza) acima. Como classificar com 'ordem' são duas operações separadas, mostrei isso usando duas linhas de código - uma criando o vetor de índice e a segunda linha usando esse índice para realizar a classificação. O OP pediu uma explicação não apenas um resultado, e eu dei-lhe uma, como evidenciado pelo fato de que ele selecionou minha resposta e escreveu a breve nota acima "Obrigado [m] faz todo o sentido". Até limitei o resultado final a uma variável chamada "fg_sorted".
doug,
24

(Achei que poderia ser útil apresentar as idéias de forma muito simples aqui para resumir o bom material postado por @doug, & vinculado por @duffymo; +1 para cada, aliás.)

? ordem informa qual elemento do vetor original precisa ser colocado primeiro, segundo, etc., de modo a classificar o vetor original, enquanto ? classificação informa qual elemento tem o valor mais baixo, o segundo mais baixo, etc. Por exemplo:

> a <- c(45, 50, 10, 96)
> order(a)  
[1] 3 1 2 4  
> rank(a)  
[1] 2 3 1 4  

Então order(a)está dizendo, 'coloque o terceiro elemento primeiro quando você classificar ...', enquanto que rank(a)está dizendo, 'o primeiro elemento é o segundo mais baixo ...'. (Observe que ambos concordam sobre qual elemento é o mais baixo, etc.; Eles apenas apresentam as informações de forma diferente.) Assim, vemos que podemos usar order()para classificar, mas não podemos usar rank()dessa forma:

> a[order(a)]  
[1] 10 45 50 96  
> sort(a)  
[1] 10 45 50 96  
> a[rank(a)]  
[1] 50 10 45 96  

Em geral, order()não será igual a rank()menos que o vetor já tenha sido classificado:

> b <- sort(a)  
> order(b)==rank(b)  
[1] TRUE TRUE TRUE TRUE  

Além disso, uma vez que order()está (essencialmente) operando sobre classificações de dados, você poderia compô-los sem afetar as informações, mas o contrário produz um jargão:

> order(rank(a))==order(a)  
[1] TRUE TRUE TRUE TRUE  
> rank(order(a))==rank(a)  
[1] FALSE FALSE FALSE  TRUE  
gung - Reintegrar Monica
fonte
1
ordere ranksão, na verdade, inversos entre si (pelo menos, desde que os valores em asejam únicos). Se você imaginar que cada um tinha nomes (/ rótulos) ('1', '2', '3', '4') em seus valores, então os valores de order(a)informam em qual posição em rank(a)cada rótulo ocorre (por exemplo, o primeiro valor de order(a)(3) informa que '1' ocorre na 3ª posição de rank(a)e vice-versa (por exemplo, o 2 ° valor de rank(a)(3) informa que '2' ocorre na 3ª posição de order(a)). Elas são permutações inversas: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b
"? ordem informa qual elemento do vetor original precisa ser colocado em primeiro, segundo, etc., para classificar o vetor original, enquanto? classificação informa qual elemento tem o valor mais baixo, o segundo mais baixo, etc." Lá. Isso é tudo que alguém tem a dizer. Finalmente. Obrigado!!
AleksandrH
explicado de forma sucinta .. o que é necessário "? a ordem informa qual elemento do vetor original precisa ser colocado em primeiro, segundo, etc., de modo a classificar o vetor original, enquanto a classificação? informa qual elemento tem o mais baixo, o segundo mais baixo , etc., valor. "
sHiBuKaLiDhAsAn
9

Executar este pequeno pedaço de código me permitiu entender a função de pedido

x <- c(3, 22, 5, 1, 77)

cbind(
  index=1:length(x),
  rank=rank(x),
  x, 
  order=order(x), 
  sort=sort(x)
)

     index rank  x order sort
[1,]     1    2  3     4    1
[2,]     2    4 22     1    3
[3,]     3    3  5     3    5
[4,]     4    1  1     2   22
[5,]     5    5 77     5   77

Referência: http://r.789695.n4.nabble.com/I-don-t-understand-the-order-function-td4664384.html

adebesina
fonte
1
O resultado não corresponde à entrada. Você deve ter usado um diferente xem cbind().
Rich Scriven
Alterado em relação aos comentários acima. Espero que isso ajude :)
adebesin
2

Isso pode ajudá-lo em algum momento.

a <- c(45,50,10,96)
a[order(a)]

O que você ganha é

[1] 10 45 50 96

O código que escrevi indica que você deseja "a" como um subconjunto inteiro de "a" e que deve ser ordenado do menor ao maior valor.

Alejandro Carrera
fonte
2

Em palavras simples, order() fornece a localização de elementos de magnitude crescente.

Por exemplo, order(c(10,20,30))vai dar 1,2,3 e order(c(30,20,10))vai dar 3,2,1 .

Arnab Jana
fonte
0

eles são semelhantes, mas não iguais

set.seed(0)
x<-matrix(rnorm(10),1)

# one can compute from the other
rank(x)  == col(x)%*%diag(length(x))[order(x),]
order(x) == col(x)%*%diag(length(x))[rank(x),]
# rank can be used to sort
sort(x) == x%*%diag(length(x))[rank(x),]
Nick Nassuphis
fonte
classificação é a permutação inversa da ordem: all(x==x[order(x)][rank(x)])é sempre verdadeiro. algumas permutações são seu próprio inverso, mas a maioria não. o inverso da permutação de classificação saindo da ordem () é classificação (). isso explica por que às vezes eles são iguais e outras não.
Nick Nassuphis