sort() Ordena os Valores de um Vetor
Para um vetor simples, sort() faz exatamente o que você espera - retorna os valores em ordem crescente (o original fica intocado):
Duas opções que vale a pena conhecer. decreasing = TRUE inverte a direção. E sort() silenciosamente descarta valores NA por padrão - sort(c(3, NA, 1)) retorna apenas 1 3. Se os valores ausentes precisam sobreviver à ordenação, diga onde eles vão: sort(x, na.last = TRUE) os mantém, colocados depois dos valores ordenados.
Até aqui, nada de novo. A parte interessante é por que sort() é a ferramenta errada para data frames.
order() Retorna Posições - A Mudança Mental
sort() responde "quais são os valores, em ordem?" order() responde a uma pergunta diferente: "quais posições eu visitaria para ver os valores em ordem?"
Leia order(times) como instruções: o menor valor está na posição 2, o próximo na posição 4, depois 1, depois 3. Indexar com essas instruções - times[order(times)] - reproduz sort(times) exatamente.
Por que isso importa? Porque uma linha de data frame é um time de valores que precisa se mover junto. Ordenar a coluna time sozinha com sort() reordenaria uma coluna e deixaria suas companheiras para trás - todas as linhas embaralhadas. order() fornece as posições das linhas, e colocar posições no espaço das linhas dos colchetes move linhas inteiras:
O 9.8 do Ben chega com o nome do Ben ainda anexado. Esse é todo o truque, e é o idioma para ordenar data frames no R base: df[order(df$column), ]. (Os rótulos de linha impressos - 2 4 1 3 - são os números originais das linhas acompanhando; inofensivo.)
Ordenações Decrescentes e por Múltiplas Colunas
Para ordenações numéricas decrescentes, negue a coluna - ordenar -time de forma crescente é ordenar time de forma decrescente. E order() aceita múltiplas colunas, as primeiras têm prioridade, as seguintes desempatam:
A segunda chamada ordena os departamentos alfabeticamente e, dentro de cada departamento, os salários do maior para o menor. O truque da negação só funciona com números - -df$name em uma coluna de texto é um erro. Para texto decrescente, use order(df$name, decreasing = TRUE) (que inverte todas as chaves de ordenação de uma vez).
rank() É o Terceiro Irmão
De passagem: rank(x) responde a mais uma pergunta - "que colocação cada valor ocupa?" - sem mover nada:
sort() fornece os valores ordenados, order() fornece as posições a visitar, rank() fornece a colocação de cada valor no lugar. As pessoas confundem order() e rank() o tempo todo; note que eles são permutações inversas um do outro, e recorra a rank() apenas quando você quer literalmente classificações (rankings, percentis).
O Jeito dplyr: arrange()
O arrange() do dplyr embrulha toda a dança do order() em um verbo - as colunas são chaves de ordenação e desc() inverte uma delas (estático; o sandbox executa apenas R base):
library(dplyr)
runners |> arrange(time)
staff |> arrange(dept, desc(salary))
Sem colchetes, sem $, sem truque de negação - desc() funciona também com colunas de texto. Uma diferença de comportamento que vale conhecer: arrange() coloca os valores NA no final independentemente da direção, enquanto o order() do R base também tem na.last = TRUE como padrão. Veja a introdução ao dplyr para saber como arrange() se encadeia com filter() e companhia.
Ordenar Texto Tem Arestas Afiadas
Duas ressalvas ao ordenar texto. Primeira: dígitos armazenados como texto são ordenados como texto - a comparação de caracteres vai símbolo por símbolo:
"10" vem antes de "2" porque a comparação para no primeiro símbolo: "1" < "2". Se uma coluna de números ordena de forma estranha, quase certamente ela está armazenada como texto - converta com as.numeric() primeiro (uma consequência frequente de uma importação de CSV bagunçada).
Segunda: a ordenação de texto depende do locale do seu sistema - acentos, maiúsculas/minúsculas e alfabetos não latinos podem ordenar de forma diferente no seu notebook e em um servidor com locale C. Uma saída ordenada que precisa ser idêntica entre máquinas deve definir o locale explicitamente ou ordenar uma chave normalizada.
O Que Você Leva Daqui
sort(x)ordena os valores de um vetor;decreasing = TRUEinverte;NAs são descartados a menos que usena.last = TRUE.order(x)retorna posições, edf[order(df$x), ]é o idioma do R base para ordenar data frames.- Múltiplas colunas:
order(df$a, -df$b); a negação para ordem decrescente funciona apenas com números. rank()fornece colocações sem reordenar - não é um substituto paraorder().- O
arrange(dept, desc(salary))do dplyr é a mesma ordenação com menos pontuação. "10"vem antes de"2"em texto - confira os tipos das suas colunas.
A seguir: colapsar linhas em resumos por grupo com table(), tapply(), aggregate() e o group_by() do dplyr.
Perguntas frequentes
Como ordeno um data frame por uma coluna no R?
Use order() dentro dos colchetes na posição das linhas: df[order(df$price), ]. order() retorna as posições das linhas em ordem, e indexar com elas reorganiza o data frame inteiro. sort() não serve aqui - ele ordena os valores de um único vetor, perdendo a conexão deles com as outras colunas.
Qual é a diferença entre sort() e order() no R?
sort(x) retorna os valores de x reorganizados em ordem. order(x) retorna as posições (índices) que colocariam x em ordem - que é o que você precisa para ordenar um data frame inteiro por uma de suas colunas: df[order(df$x), ].
Como ordeno em ordem decrescente no R?
Para um vetor: sort(x, decreasing = TRUE). Para um data frame: df[order(-df$x), ] (negue uma coluna numérica) ou df[order(df$x, decreasing = TRUE), ], que também funciona para colunas de texto, onde a negação não funciona. No dplyr: arrange(df, desc(x)).
Como ordeno por múltiplas colunas no R?
Passe todas para order(): df[order(df$dept, -df$salary), ] ordena por departamento e, dentro de cada departamento, por salário em ordem decrescente. Os primeiros argumentos são as chaves primárias; os seguintes desempatam. No dplyr: arrange(df, dept, desc(salary)).