Como tratar a ordem dos fatores com forcats no R
Fatores e Níveis
A linguagem R possui várias classes de objetos como dataframes, fatores, listas, matrizes, tibbles e vetores. E para nós que estudamos e usamos o R é indispensável saber para que cada objeto serve e como utilizar da melhor forma possível. Neste post vamos aprender um pouco sobre os fatores e sobre o pacote ideal para usar neste tipo de objeto. No R podemos definir fatores como um conjunto de categorias. Os valores que essas variáveis assumem são os níveis, ou simplesmente as categorias que compõem o fator. Os fatores são criados para representar variáveis categóricas.
Alguns exemplos de variáveis categóricas e seus níveis:
- Sexo: Masculino e Feminino.
- Continente: Ásia, África, América do Norte, América do Sul, Antártica, Europa e Oceania.
- Mês: Janeiro, Fevereiro, Março, Abril, Maio, Junho, etc.
Para criar um fator podemos utlizar a função factor()
. Vamos utilizar
um vetor sexo que armazena a informação do sexo de 7 indivíduos e depois
transformar sexo em um fator.
sexo <- c("Masculino", "Feminino", "Feminino", "Feminino", "Masculino", "Feminino", "Masculino")
sexo
## [1] "Masculino" "Feminino" "Feminino" "Feminino" "Masculino" "Feminino"
## [7] "Masculino"
fator_sexo <- as.factor(sexo)
fator_sexo
## [1] Masculino Feminino Feminino Feminino Masculino Feminino Masculino
## Levels: Feminino Masculino
Observe que ao chamar o objeto sexo e o fator_sexo eles se apresentam de maneiras diferentes. Enquanto o vetor sexo contém elementos formados por uma sequência de caracteres entre aspas, o fator_sexo é formado por níveis de um fator, os Levels, e não contém aspas.
forcats
O pacote forcats
fornece um conjunto de ferramentas que nos ajudam a
trabalhar com variáveis categóricas. Suas principais funções são:
fct_recode()
, fct_colapse()
, fct_reorder()
, fct_lump()
e
lvls_reorder()
. Para quem não tem o pacote instalado, basta rodar os
códigos a seguir.
install.packages("forcats") ## instalando o pacote forcats
library(forcats) ## carregando o pacote forcats
Além do forcats
vamos precisar do dplyr
e do ggplot2
.
library(dplyr) ## carregando o pacote dplyr
library(ggplot2) ## carregando o pacote ggplot2
Para exemplificar as funções principais, vamos usar um conjunto de dados
chamado gss_cat
que faz parte do pacote forcats
, para usar estes
dados basta apenas digitar o nome no console.
head(gss_cat) ## Vizualizando o inicio dos dados
## # A tibble: 6 x 9
## year marital age race rincome partyid relig denom tvhours
## <int> <fct> <int> <fct> <fct> <fct> <fct> <fct> <int>
## 1 2000 Never mar… 26 White $8000 to … Ind,near r… Protesta… Souther… 12
## 2 2000 Divorced 48 White $8000 to … Not str re… Protesta… Baptist… NA
## 3 2000 Widowed 67 White Not appli… Independent Protesta… No deno… 2
## 4 2000 Never mar… 39 White Not appli… Ind,near r… Orthodox… Not app… 4
## 5 2000 Divorced 25 White Not appli… Not str de… None Not app… 1
## 6 2000 Married 25 White $20000 - … Strong dem… Protesta… Souther… NA
gss_cat
é uma amostra de dados do General Social Survey
http://gss.norc.org, que é uma pesquisa norte-americana e contém uma
série de informações sobre as pessoas participantes, como o estado
civil, idade, raça, renda, partido político, religião, denominação
religiosa e a quantidade de horas que usam a TV por dia.
fct_recode()
A primeira função que veremos é a fct_recode()
. Ela tem como objetivo
alterar categorias específicas de um fator. Para exemplificar esta
função vamos usar a variável marital
de gss_cat
, esta variável
contem os níveis (No answer, Never married, Separated, Divorced,
Widowed, Married) das pessoas que participaram da
pesquisa.
head(gss_cat$marital)
## [1] Never married Divorced Widowed Never married Divorced
## [6] Married
## Levels: No answer Never married Separated Divorced Widowed Married
Os argumentos da função funcionam da seguinte forma:
fct_recode(nome_do_fator,
nível_que_queremos = "nível_que_vamos_alterar",
nível_que_queremos = "nível_que_vamos_alterar",
nível_que_queremos = "nível_que_vamos_alterar",
)
Queremos alterar todos os níveis exceto o No answer.
estado_civil <- fct_recode(gss_cat$marital,
Solteiro = "Never married",
Separado = "Separated",
Divorciado = "Divorced",
Viúvo = "Widowed",
Casado = "Married")
head(estado_civil)
## [1] Solteiro Divorciado Viúvo Solteiro Divorciado Casado
## Levels: No answer Solteiro Separado Divorciado Viúvo Casado
Os níveis que não são mencionados em fct_recode()
permanecem do mesmo
jeito que estavam.
fct_collapse()
Outra função importante do forcats
é a fct_collapse()
. Esta função
junta manualmente os níveis em categorias definidas. Usaremos novamente
os dados gss_cat
e a variável marital
. Queremos criar dois grupos de
estado civil, solteiro e casado. A fct_collapse()
segue a mesma
estrutura de argumentos que a fct_recode()
.
estado_civil2 <- fct_collapse(gss_cat$marital,
solteiro = (c("Never married", "Divorced", "Widowed", "Separated")),
casado = ("Married"))
head(estado_civil2)
## [1] solteiro solteiro solteiro solteiro solteiro casado
## Levels: No answer solteiro casado
Como o nível No answer não foi incluído na função, ele não sofreu alteração alguma.
fct_reorder()
A função fct_reorder()
tem como principal objetivo reordenar a ordem
dos níveis de fator. Vamos supor que queremos saber qual é o número
médio de horas por dia que as pessoas passam diante da TV de acordo com
cada religião. Para vizualizar esta idéia vamos criar uma tabela com
todas as informações necessárias.
relig <- gss_cat %>%
group_by(relig) %>%
summarize(
tvhours = mean(tvhours, na.rm = TRUE),
n = n()
)
head(relig)
## # A tibble: 6 x 3
## relig tvhours n
## <fct> <dbl> <int>
## 1 No answer 2.72 93
## 2 Don't know 4.62 15
## 3 Inter-nondenominational 2.87 109
## 4 Native american 3.46 23
## 5 Christian 2.79 689
## 6 Orthodox-christian 2.42 95
As funções group_by()
e summarize()
fazem parte do pacote dplyr
.
Para quem não conhece é só dar uma olhada neste
post.
Criamos a variável relig
com as informações das religões, das idades e
da média de horas gastas por dia diante da TV. Olhando apenas a tabela
acima não é possível concluir muita coisa, para uma melhor vizualização
vamos criar um gráfico com o ggplot2
.
ggplot(relig, aes(tvhours, relig)) + geom_point()
Note que as informações no gráfico ficaram todas espalhadas e
desordenadas, para resolver isso vamos usar a função fct_reorder()
.
Ela pode receber três argumentos:
fct_reorder(f = "argumento 1", x = "argumento 2", fun = "argumento 3")
O primeiro argumento, f, é o fator cujo níveis queremos modificar. O
segundo argumento, x, é um vetor numérico que queremos usar para
reordenar os níveis. O terceiro argumento, fun, é uma função que é
usada se houver múltiplos valores de x para cada valor de f. No
nosso exemplo o argumento f é a nossa tabela relig
e o nosso
argumento x é a variável tvhours
.
ggplot(relig, aes(tvhours, fct_reorder(relig, tvhours))) +
geom_point()
Observando o gráfico ordenado podemos concluir que as pessoas que seguem o Hinduímos e outras religiões orientais passam menos horas em frente a TV do que as pessoas nativo americanas e protestantes.
fct_lump()
Esta função ajuda a agrupar as categorias menores em apenas um grupo denominado other. Para este exemplo vamos utilizar a variável relig novamente.
gss_cat %>%
count(relig, sort = TRUE)## Conta a quantidade de observações em cada categoria em ordem decresecente
## # A tibble: 15 x 2
## relig n
## <fct> <int>
## 1 Protestant 10846
## 2 Catholic 5124
## 3 None 3523
## 4 Christian 689
## 5 Jewish 388
## 6 Other 224
## 7 Buddhism 147
## 8 Inter-nondenominational 109
## 9 Moslem/islam 104
## 10 Orthodox-christian 95
## 11 No answer 93
## 12 Hinduism 71
## 13 Other eastern 32
## 14 Native american 23
## 15 Don't know 15
Na variável relig
, a religião que possui um maior número de pessoas é
a Protestante, ao aplicar a função fct_lump
todas as outras religiões
menores serão agrupadas em apenas uma.
gss_cat %>%
mutate(relig = fct_lump(relig)) %>%
count(relig)
## # A tibble: 2 x 2
## relig n
## <fct> <int>
## 1 Protestant 10846
## 2 Other 10637
Apesar dos americanos participantes da pesquisa serem em grande número
protestantes, nós deixamos outras religiões com quantidades
significativas de fora. Para especificar melhor quais as observações
queremos agrupar, vamos usar um argumento n dentro da função
fct_lump()
.
gss_cat %>%
mutate(relig = fct_lump(relig, n = 5)) %>%
count(relig, sort = TRUE)
## # A tibble: 6 x 2
## relig n
## <fct> <int>
## 1 Protestant 10846
## 2 Catholic 5124
## 3 None 3523
## 4 Other 913
## 5 Christian 689
## 6 Jewish 388
Usamos o argumento n para especificar quantos grupos queremos manter fora do agrupamento. Assim podemos ver que os católicos, os cristãos e os judeus também estão em número expressivo na pesquisa.
Dentro de fct_lump()
temos quatro funções: fct_lump_min()
,
fct_lump_prop()
, fct_lump_n()
e fct_lump_lowfreq()
.
fct_lump_min():
agrupa os níveis de fator que aparecem com menor frequência do que uma quantidade determinada de vezes.fct_lump_n():
agrupa todos os níveis, exceto os n níveis mais frequentes.fct_lump_prop():
agrupa os níveis que aparecem em menos proporção.fct_lump_lowfreq():
agrupa os níveis menos frequentes.
Aqui há algumas aplicações destas funções.
lvls_reorder()
Esta função tem como objetivo modificar a ordem dos níveis de um fator.
Para exemplificar, vamos utilizar a variável marital
.
fator <- head(gss_cat$marital)
fator
## [1] Never married Divorced Widowed Never married Divorced
## [6] Married
## Levels: No answer Never married Separated Divorced Widowed Married
Note que os níveis estão ordenados assim: No answer, Never married, Separated, Divorced, Widowed, Married.
Para modificar a ordem basta imaginarmos que cada nível tem uma posição, um índice, e o que temos que fazer é reorganizar estas posições. Então ficaria assim:
Os níveis estão ordenados: No answer(1), Never married(2), Separated(3), Divorced(4), Widowed(5), Married(6).
Queremos que seja: Divorced(4), Married(6), Never married(2), No answer(1), Separated(3), Widowed(5).
lvls_reorder(fator, c(4, 6, 2, 1, 3, 5))
## [1] Never married Divorced Widowed Never married Divorced
## [6] Married
## Levels: Divorced Married Never married No answer Separated Widowed
Além destas funções apresentadas até agora, o forcats
possui outras
funções bastante úteis. Para exemplificar algumas vamos criar um fator
com letras e fazer alguns testes.
fator <- factor(c("b", "b", "d", "c", "a", "d", "d", "d", "c"))
fator
## [1] b b d c a d d d c
## Levels: a b c d
A primeira função é a fct_relevel()
, com ela é possível ordenar os
níveis manualmente. Observe que os níveis sempre são ordenados
automaticamente em ordem alfabética, para controlar isso é só escrever a
ordem desejada no segundo argumento da função.
fct_relevel(fator, c("d", "a", "c", "b"))
## [1] b b d c a d d d c
## Levels: d a c b
Esta função é similiar a lvls_reorder()
, a diferença é que a
fct_relevel()
considera os níveis de fator para reordenar enquanto na
lvls_reorder()
utilizamos os índices (1, 2,…) dos níveis.
Uma outra função que vale a pena ser comentada é a fct_infreq()
. Ela
tem como objetivo organizar os níveis de um fator por sua frequência.
fct_infreq(fator)
## [1] b b d c a d d d c
## Levels: d b c a
Note que agora as ordens dos níveis são: d, b, c, a. A mudança foi feita pois no nosso fator ‘fator’ há quatro vezes a letra ‘d’, duas vezes a letra ‘b’, duas vezes a letra ‘c’ e apenas uma vez a letra ‘a’.
Falando ainda em frequências, temos a função fct_count()
, ela cria uma
tabela de frequências dos níveis de um fator.
fct_count(fator)
## # A tibble: 4 x 2
## f n
## <fct> <int>
## 1 a 1
## 2 b 2
## 3 c 2
## 4 d 4
Neste exemplo, a letra ‘f’ representa os níveis (a, b, c, d), e a letra ‘n’ representa a frequência em que cada nível aparece no fator.
Outra função interessante é a fct_unique()
, ela remove os níveis
duplicados em um fator para que haja apenas um valor de cada nível.
fct_unique(fator)
## [1] a b c d
## Levels: a b c d
Repare que o R só printou um único valor de cada nível.
Agora vamos ver um exemplo da função fct_c()
, ela combina dois
fatores. Ja temos o fator ‘fator’, agora vamos criar o ‘fator2’.
fator2 <- factor(c("g", "h"))
fct_c(fator, fator2)
## [1] b b d c a d d d c g h
## Levels: a b c d g h
Veja que a função fct_c()
juntou os dois fatores e deu origem ao novo
fator com os níveis: a, b, c, d, g, h.
Estas foram algumas das funções que o forcats
tem a nos oferecer. Se
fosse possível acrescentaríamos muitas outras funções deste pacote,
porém o post tem que acabar. Para saber mais sobre o assunto recomendo
uma leitura nos links abaixo.