Geralmente, é necessário realizar preparações nos dados antes de executar etapas de análise. Essas etapas são frequentemente de grande importância e também bastante demoradas.
Existem alguns pacotes que permitem a manipulação de conjuntos de dados. Um dos pacotes mais conhecidos e frequentemente utilizado devido à sua compreensibilidade é o dplyr. A ideia por trás do dplyr é que ele processa apenas tabelas (data frames ou tibbles) e facilita o processamento através do chamado pipe. O código no dplyr é encadeado em uma longa sequência, o que pode parecer desnecessário a princípio. No entanto, isso torna o código legível e é necessário aprender apenas algumas funções que podem representar as etapas de processamento mais comuns quando combinadas. Com essa divisão em etapas menores, cada função tem um escopo bem definido e é facilmente compreensível. Ao combinar várias funções, também é possível realizar etapas mais complexas. Além disso, as funções do pacote dplyr sempre retornam um tibble (tabela).
A extensa documentação do dplyr pode ser encontrada aqui.
As funções mais comuns utilizadas com o dplyr são as seguintes:
| Funktion | Operation |
|---|---|
| select() | Spalte(n) wählen |
| slice() | Zeile(n) wählen |
| filter() | Zeile(n) filtern |
| arrange() | Zeile(n) ordnen |
| mutate() | neue Spalten / Variablen |
| summarize() | Werte zusammenfassen |
| group_by() | gruppieren |
Estas serão apresentadas passo a passo, antes de aprendermos sobre o piping, o segundo princípio do dplyr. Estes exemplos são de certa forma artificiais, pois o dplyr é quase exclusivamente utilizado com piping. No entanto, para entender as funções, é útil conhecê-las antecipadamente.
Em todos os exemplos, utilizamos um conjunto de dados fictício que questionou a motivação dos estudantes das universidades de Gießen, Marburg e Frankfurt.
Uma visão geral do conjunto de dados está disponível aqui:No conjunto de dados, foram questionados, entre outros, a satisfação com a democracia (stfdem), o distrito (district), a confiança no parlamento (trstprl) e o gênero (gndr).
O package dplyr pode ser carregado individualmente, mas é recomendável carregar o package tidyverse, que carrega diretamente outros pacotes como ggplot2.
# install.packages(
# "tidyverse",
# dependencies = TRUE
# )
library("tidyverse")
Com a função select(), é possível selecionar uma ou várias colunas de um conjunto de dados. A saída é sempre um tibble.
No exemplo, queremos visualizar apenas as variáveis gênero (gndr) e distrito (district).
head(pss)
## idno district gndr agea edu wkhtot income stfdem stfeco
## 1 10000 Distrikt 1 male 41 ES-ISCED IV 34 7th decile 7 6
## 2 10001 Distrikt 1 male 65 ES-ISCED II 20 6th decile 8 7
## 3 10002 Distrikt 1 male 48 ES-ISCED IV 27 7th decile 6 6
## 4 10003 Distrikt 1 female 49 ES-ISCED V 30 6th decile 5 4
## 5 10004 Distrikt 1 female 48 ES-ISCED IV 29 5th decile 4 5
## 6 10005 Distrikt 1 female 64 ES-ISCED V 30 6th decile 6 6
## trstprl trstprt trstplt trstlgl lrscale
## 1 3 5 4 6 4
## 2 5 5 5 4 3
## 3 4 4 6 5 6
## 4 2 7 4 3 6
## 5 6 6 6 6 2
## 6 1 3 2 4 7
select(
pss,
c(
gndr,
district
)
)
Por outro lado, com slice(), podemos exibir linhas individuais. Por exemplo, as linhas de \(50\) a \(55\) ou em combinação com a função seq(), a cada \(100.\) linha.
slice(
pss,
50:55
)
## idno district gndr agea edu wkhtot income stfdem stfeco
## 1 10049 Distrikt 1 female 65 ES-ISCED II 30 4th decile 5 7
## 2 10050 Distrikt 1 female 47 ES-ISCED IV 30 5th decile 5 2
## 3 10051 Distrikt 1 female 57 ES-ISCED III 21 5th decile 4 5
## 4 10052 Distrikt 1 male 42 ES-ISCED IV 27 9th decile 3 5
## 5 10053 Distrikt 1 female 47 ES-ISCED III 38 5th decile 5 5
## 6 10054 Distrikt 1 female 43 ES-ISCED III 42 2nd decile 10 6
## trstprl trstprt trstplt trstlgl lrscale
## 1 6 5 6 7 7
## 2 2 5 7 4 5
## 3 5 6 2 4 3
## 4 5 4 5 5 5
## 5 4 3 0 5 2
## 6 8 5 7 4 3
slice(
pss,
seq(
0,
1000,
100
)
)
## idno district gndr agea edu wkhtot income stfdem stfeco
## 1 10099 Distrikt 1 female 53 <NA> 41 7th decile 5 6
## 2 10199 Distrikt 1 male 58 ES-ISCED III 39 5th decile 6 5
## 3 10299 Distrikt 1 female 45 ES-ISCED III 29 5th decile 4 6
## 4 10399 Distrikt 1 female 63 ES-ISCED III 37 5th decile 7 6
## 5 10499 Distrikt 1 female 56 ES-ISCED IV 38 6th decile 5 5
## 6 10600 Distrikt 1 male 71 ES-ISCED II 44 5th decile 7 7
## 7 10700 Distrikt 1 male 70 ES-ISCED III 30 6th decile 4 6
## 8 10800 Distrikt 1 male 75 ES-ISCED II 48 5th decile 8 6
## 9 10900 Distrikt 1 male 67 ES-ISCED II 48 3rd decile 4 4
## 10 11000 Distrikt 1 female 69 ES-ISCED III 41 5th decile 4 5
## trstprl trstprt trstplt trstlgl lrscale
## 1 1 4 4 8 8
## 2 6 4 4 5 8
## 3 7 3 6 2 5
## 4 4 5 6 6 8
## 5 3 5 4 7 6
## 6 5 4 4 4 7
## 7 3 7 7 3 8
## 8 5 10 4 5 6
## 9 3 3 4 3 5
## 10 6 3 5 4 7
Além da seleção de linhas (casos) ou colunas (variáveis) específicas, podemos restringir o conjunto de dados com filter(). Por exemplo, podemos exibir apenas os casos que vivem no Distrito 1.
filter(
pss,
district == "Distrikt 1"
)
Também podemos introduzir várias condições. Por exemplo, apenas pessoas que vivem no Distrito 5 e são do sexo masculino (male).
filter(
pss,
district == "Distrikt 5" & gndr == "male"
)
Todas as conexões lógicas conhecidas funcionam aqui também. Como lembrete, aqui estão os conectores lógicos novamente:
e lógico: &
ou lógico: |
igual a lógico: ==
diferente de lógico: !=
maior que lógico: >
menor que lógico: <
menor ou igual a lógico: <=
maior ou igual a lógico: >=
Para ordenar conjuntos de dados, a função arrange() pode ser usada. Aqui, você pode ordenar de forma ascendente ou descendente. Por exemplo, por horas de trabalho:
pssAsc <- arrange(
pss,
wkhtot
)
head(pssAsc)
## idno district gndr agea edu wkhtot income stfdem stfeco
## 1 20438 Distrikt 5 male 37 ES-ISCED II 6 6th decile 4 4
## 2 10078 Distrikt 1 male 54 ES-ISCED IV 7 9th decile 6 4
## 3 20249 Distrikt 5 male 48 ES-ISCED IV 7 9th decile 5 5
## 4 10072 Distrikt 1 male 52 ES-ISCED IV 8 9th decile 2 5
## 5 10757 Distrikt 1 male 37 ES-ISCED IV 9 8th decile 4 5
## 6 20103 Distrikt 5 female 25 ES-ISCED IV 9 6th decile 3 0
## trstprl trstprt trstplt trstlgl lrscale
## 1 6 5 4 3 3
## 2 1 7 3 7 9
## 3 4 5 4 6 6
## 4 3 1 4 2 7
## 5 4 6 4 5 7
## 6 1 5 3 4 1
Usando a função desc() dentro de arrange(), os casos são classificados em ordem decrescente. desc significa descending, ou seja, descendente. Alternativamente, você pode simplesmente adicionar um sinal de menos antes do nome da variável e também obter casos classificados em ordem decrescente.
pssDesc <- arrange(
pss,
desc(wkhtot)
)
head(pssDesc)
## idno district gndr agea edu wkhtot income stfdem stfeco
## 1 40446 Distrikt 10 male 63 <NA> 65 1st decile 5 6
## 2 50618 Distrikt 12 female 51 <NA> 63 2nd decile 5 6
## 3 50494 Distrikt 12 female NA ES-ISCED II 62 2nd decile 3 4
## 4 50491 Distrikt 12 female NA ES-ISCED III 60 4th decile 5 4
## 5 20294 Distrikt 5 male 59 ES-ISCED III 59 6th decile 7 8
## 6 40525 Distrikt 10 male 40 ES-ISCED II 59 4th decile 3 7
## trstprl trstprt trstplt trstlgl lrscale
## 1 2 2 9 5 7
## 2 5 4 6 4 5
## 3 3 3 4 2 1
## 4 3 6 6 6 3
## 5 6 4 7 3 5
## 6 1 3 4 1 4
# Alternativ Minuszeichen vor Variable
pssDesc2 <- arrange(
pss,
-wkhtot
)
Para calcular novas variáveis ou recodificar uma variável, usamos mutate(). No exemplo, calculamos uma variável que mostra a diferença em relação ao tempo médio de trabalho em nossa pesquisa.
mutate(
pss,
wkhtotCen = wkhtot - mean(wkhtot, na.rm = TRUE)
)
Se quisermos criar novas variáveis dummy ou categóricas, precisamos usar a função case_when() adicionalmente. Na função case_when(), especificamos hierarquicamente quais condições devem ser verificadas e como devem ser recodificadas. Por exemplo, poderíamos recodificar a variável district e transformar a variável character em uma variável integer. É importante que as verificações sejam feitas em ordem hierárquica, como em uma condição if, do mais específico para o mais geral (caso contrário, teremos variáveis sem sentido!).
mutate(
pss,
districtRec = case_when(
district == "Distrikt 1" ~ 1,
district == "Distrikt 5" ~ 5,
district == "Distrikt 7" ~ 7,
district == "Distrikt 10" ~ 10,
district == "Distrikt 12" ~ 12,
)
)
Aqui também é possível combinar várias condições: Agora queremos calcular um dummy que indica se as pessoas vivem no Distrito 12 e são do sexo feminino (female).
mutate(
pss,
d12gndr = case_when(
district == "Distrikt 12" & gndr == "female" ~ 1
)
)
Neste exemplo, agora especificamos apenas uma condição para atribuir o valor 1 à nova variável. Como podemos ver, todos os outros casos são automaticamente atribuídos como NA. No entanto, queremos atribuir o valor 0 a todos os outros casos. Para não ter que escrever as diferentes combinações, usamos outro argumento da função case_when():
mutate(
pss,
d12gndr = case_when(
district == "Distrikt 12" & gndr == "female" ~ 1,
TRUE ~ 0
)
)
Com o argumento TRUE ~ 0, definimos que todos os outros valores recebem o valor 0. Assim, não é necessário escrever todos as outras combinações como código.
A função summarize() nos permite resumir um valor de colunas. Por exemplo, a média de uma coluna.
summarize(
pss,
mean(wkhtot)
)
## mean(wkhtot)
## 1 34.3008
Qualquer função que exija uma coluna como entrada pode ser usada: Portanto, entre outras, first(), last(), nth(), n(), n_distinct(), IQR(), min(), max(), mean(), median(), var() e sd().
Muitas vezes, temos variáveis categóricas nos conjuntos de dados pelas quais queremos agrupar o conjunto de dados. Por exemplo, poderíamos agrupar o conjunto de dados por área de estudo. Fazemos isso com a função group_by():
group_by(
pss,
gndr
)
Parece que nada mudou no conjunto de dados, mas aqui está a diferença importante em relação ao arrange(): group_by() não classifica o conjunto de dados, mas o agrupa. Portanto, a saída não muda. Se quisermos, por exemplo, exibir a média dos semestres por área de estudo, concatenamos group_by() e summarize() (mais adiante faremos isso de forma mais elegante com o Operador de Tubulação):
summarize(
group_by(
pss,
gndr
),
mean(wkhtot)
)
## # A tibble: 2 × 2
## gndr `mean(wkhtot)`
## <fct> <dbl>
## 1 female 34.5
## 2 male 34.1
Aqui está o texto traduzido para o português brasileiro:
Aqui vemos agora o que group_by() faz: Em vez de uma média, agora obtemos quatro médias (uma para cada curso no conjunto de dados). Importante: A desagregação deve sempre ser resolvida posteriormente com a função ungroup().