O Que um Fator Realmente É
Um fator é a resposta do R para dados categóricos - valores que vêm de um cardápio fixo de possibilidades: grupos de tratamento, respostas de pesquisa, tamanhos de camiseta. Parece um vetor de caracteres quando impresso, mas não é um. Internamente, um fator é um vetor de códigos inteiros mais uma tabela de consulta de rótulos chamados de níveis:
A impressão mostra os rótulos e depois uma linha Levels: listando o cardápio. as.integer() expõe a engrenagem: os códigos voltam como 3 1 3 2, porque cada valor é na verdade um índice na tabela de níveis - e os níveis são ordenados alfabeticamente por padrão (large, medium, small), não na ordem em que os dados chegaram. Então small é o código 3 e large é o código 1, o que não é a intuição de ninguém. Lembre-se desse padrão alfabético; ele causa duas das armadilhas abaixo.
Por que se dar ao trabalho desse design em duas camadas em vez de strings simples? Porque a estatística precisa dele. Um modelo não consegue multiplicar "small" por um coeficiente - mas consegue codificar três níveis conhecidos em colunas de 0s e 1s. Funções como lm(), glm(), table() e a maquinaria por trás da ANOVA usam fatores para saber que uma variável é categórica, qual é o conjunto completo de categorias (incluindo as ausentes dos dados) e qual categoria é a linha de base. Vetores de caracteres simples não carregam nada disso.
Criando Fatores: levels, labels e table()
Por padrão, factor() pega os valores distintos que encontra e os ordena alfabeticamente em níveis. Muitas vezes você vai querer controle tanto sobre o conjunto quanto sobre a ordem - passe levels =:
Agora os níveis seguem sua ordem natural de tamanho, e table() - a contagem de frequências de uma linha que você vai usar o tempo todo com fatores - reporta as contagens nessa ordem também. nlevels() conta as categorias.
Mais duas coisas que levels = te dá. Valores nos dados que não estão na sua lista de níveis viram NA (o que é bom: erros de digitação aparecem em vez de virarem sua própria categoria). E níveis com zero ocorrências continuam existindo, então um resumo de respostas de pesquisa mostra "discordo totalmente: 0" em vez de fingir que a opção nunca existiu.
labels = renomeia os níveis no momento da criação, o que é prático quando os dados brutos usam códigos:
E as.factor(x) é o conversor rápido para um vetor existente quando os padrões servem.
Fatores Ordenados para Dados Ordinais
Fatores comuns tratam categorias como não ordenadas - "red" não é menor que "blue". Mas algumas escalas categóricas têm uma hierarquia genuína: baixo/médio/alto, discordo/neutro/concordo. Declare isso com ordered = TRUE:
A impressão agora mostra Levels: low < medium < high, e os operadores de comparação funcionam: você pode perguntar se uma avaliação supera outra, ou filtrar tudo igual ou acima de "medium" - ambos dariam erro (bem, avisos e NAs) em um fator não ordenado. Fatores ordenados também mudam como os modelos codificam a variável (contrastes polinomiais em vez de variáveis dummy), o que normalmente é o que você quer para preditores ordinais.
Use ordered = TRUE apenas quando a hierarquia é real. Codificar grupos comuns como ordenados muda a saída do modelo de formas fáceis de interpretar errado.
O Nível de Referência e relevel()
O primeiro nível de um fator é especial: funções de modelo o tratam como a categoria de referência, a linha de base contra a qual o coeficiente de todo outro nível é medido. Como a ordem padrão dos níveis é alfabética, sua linha de base é escolhida pelo alfabeto a menos que você intervenha - e "control" perder para "aspirin" no alfabeto não é uma decisão científica.
relevel() promove um nível ao primeiro lugar:
Antes: control acaba sendo o primeiro apenas por sorte alfabética. Depois de relevel(..., ref = "control") ele é o primeiro de propósito. Em uma regressão linear com esse preditor, o coeficiente de treatment agora responde "como o tratamento difere do controle?" - a pergunta que você de fato fez. Sempre que os coeficientes categóricos de um modelo parecerem confusos, cheque primeiro o nível de referência.
(Para reordenar tudo - não apenas o primeiro lugar - passe de novo um vetor levels = completo para factor().)
A Armadilha Clássica: Converter um Fator em Numérico
Às vezes números chegam como fatores - normalmente uma coluna de CSV que continha um valor não numérico perdido. Converter de volta parece óbvio e dá memoravelmente errado:
as.numeric(f) retorna 2 1 3. Não 20, 10, 30 - os códigos de nível. Os níveis ordenam alfabeticamente para "10", "20", "30", então "20" é o nível 2 e converte para... 2. Sem erro, sem aviso, pequenos inteiros de aparência plausível substituindo silenciosamente seus dados. Análises já foram retratadas por causa disso.
O caminho correto passa por caractere: as.numeric(as.character(f)) primeiro recupera os rótulos como texto, depois interpreta o texto como números - 20 10 30. Grave esse idioma: de fator para numérico sempre passa por as.character().
droplevels() e a História do stringsAsFactors
Fazer subconjunto de um fator mantém o conjunto completo de níveis, mesmo para categorias que não aparecem mais:
Depois de filtrar large, table() ainda o reporta - com contagem 0. Às vezes isso é exatamente o certo (você quer a categoria vazia visível). Quando não é - grupos com contagem zero poluem gráficos e podem quebrar análises estratificadas - droplevels() descarta os níveis sem observações.
Uma nota histórica de que você vai precisar ao ler código antigo ou respostas do Stack Overflow: antes do R 4.0 (2020), data.frame() e read.csv() convertiam toda coluna de caracteres em fator automaticamente - stringsAsFactors = TRUE era o padrão. Uma década de tutoriais está repleta de contornos para fatores que ninguém pediu. Desde o R 4.0 o padrão é FALSE: strings continuam strings, e você cria fatores deliberadamente, onde uma variável do seu data frame é genuinamente categórica. Esse é o hábito certo - fatores explícitos, de propósito, com níveis que você escolheu.
O Que Você Leva Daqui
- Um fator = códigos inteiros + rótulos de nível; é o que diz às funções estatísticas que uma variável é categórica.
- Controle o conjunto e a ordem das categorias com
levels =, renomeie comlabels =, conte comtable(). ordered = TRUEhabilita comparações para escalas genuinamente ordinais.- O primeiro nível é a linha de base do modelo - defina-o deliberadamente com
relevel(f, ref = ...). - Nunca use
as.numeric(f)diretamente - sempreas.numeric(as.character(f)). droplevels()limpa níveis não usados depois de um subconjunto; desde o R 4.0, strings continuam strings a menos que você mesmo crie fatores.
A seguir: data frames - onde fatores, números e texto convivem como colunas de uma mesma tabela.
Perguntas frequentes
O que é um fator no R?
Um fator é o tipo do R para dados categóricos - valores extraídos de um conjunto fixo de possibilidades chamado de níveis (levels). Internamente é um vetor de códigos inteiros mais uma tabela de rótulos de nível, e é isso que permite às funções estatísticas tratarem categorias corretamente (contando-as, codificando-as como variáveis dummy em modelos) em vez de tratá-las como texto livre.
Como converter um fator em numérico no R?
Passe por caractere: as.numeric(as.character(f)). Chamar as.numeric(f) diretamente retorna os códigos internos de nível (1, 2, 3, ...), não os valores que os rótulos mostram - então um fator exibindo "20" pode voltar como 2. Esse é um dos bugs silenciosos mais comuns do R.
O que a função relevel() faz no R?
Ela move um nível escolhido para a primeira posição: relevel(group, ref = "control"). O primeiro nível é a categoria de referência (linha de base) contra a qual funções de modelo como lm() e glm() comparam todos os outros níveis, então escolhê-lo deliberadamente faz os coeficientes da regressão significarem o que você pretende.
Por que meu fator ainda mostra níveis que eu removi?
Fazer um subconjunto de um fator mantém o conjunto completo de níveis mesmo quando alguns não ocorrem mais, então table() mostra categorias com contagem zero e os modelos ainda reservam espaço para elas. Rode droplevels() no subconjunto para descartar os níveis não usados.