Aula 3

Manipulação de dados

Na aula de hoje, antes de retornar as ferramentas de manipulação de dados iremos entender um pouco melhor sobre tipos de dados e estruturas de dados.

Objetos e atribuições I

“To understand computations in R, two slogans are helpful: • Everything that exists is an object. • Everything that happens is a function call.” — John Chambers

Dados são guardados dentro de objetos. Objetos possuem diferentes formas de estruturas os dados. Podemos ter objetos de diferentes tipos: Vetores Listas Dataframes

Objetos podem conter dados de diferentes tipos, como: Números Strings Fatores

Atribuindo valores à variáveis (<-)

Ocorre que os códigos digitados até aqui apenas são executados no console, o que significa que não estamos salvando estes objetos na memória do computador, o que não nos possibilita manipular as estruturas de uma forma mais fácil.

1
a <- 1
a
b <- (“Hello, world”)
b
dado <- c(1,2,3,4,5,6)
dado

Tipos de dados

knitr::include_graphics("imgs/TipoDeDados.png")

plot of chunk unnamed-chunk-2

Lidando com números

O tipo mais comum de dado é o tipo númerico. O número de votos que um candidato recebeu, número de ministérios em cada governo e a taxa de sucesso do Executivo e etc.. Estes valores podem ser classificados em dois tipos: Inteiros e Reais.

3 # numero inteiro
55.4 # numero real

Lidando com texto

Outro tipo de dado muito conhecido é o tipo texto, ou também chamado strings. Para formarmos um dado do tipo texto basta utilizarmos aspas simples ('') ou aspas duplas (""), mas lembre-se não podemos intercalar as aspas, como por exemplo, 'olá mundo".

"Vargas"
'Janio Quadros'
"1945"

Perceba que devido ao fato de 1945 estar entre aspas, ele não é mais um dado do tipo número, mas sim texto.

Lidando com fatores

Vamos supor que estamos trabalhando com dados de survey e em uma das questões temos a escala likert, em que as respostas vão do “Discordo totalmente” até o “Concordo totalmente” contabilizando um total de 6 categorias de resposta. Ocorre que para que o R entenda este tipo de dado como algo categórico, precisamos transformá-los em fatores (factors).

Para fazer essa transformação, utilizaremos uma função chamada factor() que recebe como parâmetro um vetor com o que queremos transformar em categorias.

factor(c("Discordo totalmente", "Discordo parcialmente", "Indiferente", "Concordo parcialmente", "Concordo totalmente"))

Diferente de quando executamos um dado tipo texto, os dados categóricos apresentam os níveis das categorias (levels). Perceba que as nossas categorias não estão de acordo com o que a escala likert pressupõe e para arrumar este problema, precisamos definir os níveis através de um outro parâmetro da função factor() chamado levels =.

factor(c("Discordo totalmente", "Discordo parcialmente", "Indiferente", "Concordo parcialmente", "Concordo totalmente"),
       levels = c("Discordo totalmente", "Discordo parcialmente", "Indiferente", "Concordo parcialmente", "Concordo totalmente"))

Pode parecer um pouco confuso agora, mas iremos esclarecer estes pontos nos próximos tópicos.

Lidando com lógicos/booleanos

Valores booleanos são resultados de operações booleanas e podem ser definidos como verdadeiros ou falsos. Por convenção, trabalhamos com os termos em inglês. Portanto, TRUE ou FALSE.

Por operações booleanas, podemos pensar em diferentes testes que tenham necessariamente uma resposta ou verdadeira ou falsa. Por exemplo, 3 é maior do que 1? Verdadeiro! E 3 é menor do que 2? Falso!

Vamos realizar essas duas operações no R.

# 3 é maior do que 1?
3 > 1
# 3 é maior do que 1?
3 < 2

Existem, obviamente, outras operações. É possível também testar a igualdade entre dois valores com ==.

# 2 é igual a 2?
2 == 2

Também podemos testar se dois valores são diferentes.

#120 é diferente de 20?
120 != 20

Outras variações utilizadas são o maior ou igual (>=) e o menor ou igual (<=). Além disso, também é possível realizar essas operações com textos.

# "harvard" é igual a "MIT"?
"Harvard" == "MIT"

Não iremos introduzir essa ideia aqui, mas caso seja de interesse também podemos utilizar as noções de maior e menor para textos. Você teria um palpite de como um texto pode ser maior do que outro?

Além disso, o TRUE/FALSE, como veremos adiante, podem ser utilizados em parâmetros de funções, como por exemplo, “Você gostaria que ao fazer a média de um conjunto de valores sejam removidos os valores ausentes?”. Se você preenche com TRUE, o resultado provavelmente será númerico, caso preencha com FALSE e você tenha dados ausentes, com toda certeza seu resultado será um valor ausente, ou também chamado de missing.

Valores ausentes/ missings

Existem dois tipos de valores missing, o NA (not avaible) e o NaN (not a number), ambos tem sentidos semelhantes, porém o primeiro é mais genérico para cada tipo de dado. Para sabermos se um certo dado é missing, utilizamos a função is.na().

is.na(NA)
is.na(99)

Manipulação de bancos de dados

A manipulação de dados é a parte do trabalho que antecepe a produção de gráfico e a análise dos resultados. Seja se você está utilizando uma base de dados produzida por terceiros ou de produção própria, utilizará ferramentas de manipulação de dados. Tais ferramentas são essenciais para que você consiga obter o resultado final desejado com a sua análise. Com essas ferramentas você poderá: - visualizar as informações que o banco fornece, permitindo checagens e pequenas explorações - criar novas variáveis a partir de variáveis já extistentes no banco. - modificar a estrutura do banco, seja modificando nome de variáveis, e quais as variáveis são de seu interesse. - agregar informações de outras bases de dados.

Depois de todo o processso de manipulação, você obterá sua própria base de dados!

Por que utilizamos o pacote tidyverse para manipular dados?

Nós que utilizamos a programação sem sermos programadores nos favorecemos com a criação de pacotes como o tidyverse. Esse super pacote abriga dentro de si uma série de outros pacotes (que podem ser utilizados separadamente, mas que poupam muito trabalhando sendo reunidos em um só) que dão conta de todas as etapas do ciclo da ciência de dados.

  • Importação (readr, DBI)

  • Tidy (tidyr)

  • Transformação (dplyr)

  • Visualização (ggplot2)

  • Modelagem (modelr)

Nas aulas três e quatro passaremos pela importação, mas nosso foco será a transformação de nossas bases em formato tidy e a manipulação de dados utilizando o dplyr.

Começando pelo começo

Para utilizar o tidyverse temos que instalá-lo e habitá-lo em nossos computadores. Então, vamos nessa!

install.packages("tidyverse")
library(tidyverse)

Tydr R

Existem dois conjuntos de pacotes que utilizamos para estruturar bancos de dados

  • 1º conjunto: estrutura como as variáveis aparecem

Derreter (gather) Esticar (spread)

  • 2º conjunto: permite unir o conteúdo de dois ou mais variáveis

Unir (unite) Separar (separate)

Tidyr parte 1: Estruturar o seu banco de dados no formato tidy

Esse primeiro conjunto de variáveisé aquele capaz de realizar modificações estruturais no nosso banco de dados, e antes de explicar o que isso quer dizer vamos comparar duas bases de dados que trazem as mesmas informações, mas com estruturas diferentes para pensarmos no impacto que isso gera sobre a utilização dos funções.

Primeiro, importe esse banco.

VOTOS_PRIMEIROTURNO_UF_2018 <- read_csv("VOTOS_PRIMEIROTURNO_UF_2018.csv")

O que esse banco mostra? O total de votos que todos os candidatos à presidência obtiveram no primeiro turno da eleição.

VOTOS_PRIMEIROTURNO_UF_2018_2 <- read_csv("VOTOS_PRIMEIROTURNO_UF_2018_2.csv")

Nesse segundo banco, temos a mesma informação. Mas a estrutura do banco está diferente, os estados deixaram de ser representados em uma mesma coluna passando a nomear novas colunas. Qual dos dois bancos seria o ideal para aplicar as ferramentas de manipulação?

Para entender a diferença e saber qual é o melhor, temos que pensar como queremos agregar a informação sobre os estados em nossa análise. A informação sobre os estados é também uma variável que se agrega dentro da variável de UFs, o que quer dizer que quando ela está da forma não tidy, não conseguimos aplicar muitos das funções de manipulação.

O formato da primeira tabela é o que consideramos tidy, esse formato é o ideal para que possamos aplicar os verbos do pacote tidyverse.

Existe um comando que é capaz de realizar ambas as transformações.

Gather:

Caso quereiramos transformar o segundo banco no formato tidy pode usar o comando gather. Esse comando derrete/agrupa colunas em duas colunas finais

gather(dataframe, intervalos de colunas, key, values)

data = Data frame a ser remodelado ‘intervalos de colunas’ = Nomes ou índices numéricos das colunas agrupadas key = Nome da nova coluna-chave (character string) value = Nome da nova coluna de valores

VOTOS_PRIMEIROTURNO_UF_2018_tidy <- gather(VOTOS_PRIMEIROTURNO_UF_2018, AC:ZZ, key = "UF", value = "QTDE_VOTOS")

Spread

Com essa função, podemos fazer com que uma das variáveis se transforme em nome das variáveis, ou seja,gera multiplas colunas a partir de duas colunas.

spread(data, key, values)

Data = dataframe a ser remodelado key = Coluna para usar para as ‘chaves’ (nomes das novas colunas) values = Coluna para usar para os valores (novas células nas colunas)

VOTOS_PRIMEIROTURNO_UF_2018_2_spread <- spread(VOTOS_PRIMEIROTURNO_UF_2018_2, UF, QTDE_VOTOS)

Unite e separate

Vamos começar pela unite. Essa função permite a criação de uma nova variável formada pelo conteúdo de duas outras delas. Ou seja, ela concatena duas ou mais informações.

Vamos unir então o ano da eleição e o turno.

unite(banco, “nova_variavel”, primeira_variavel, segunda_variavel, sep = “ - “)

VOTOS_PRIMEIROTURNO_UF_2018_2_unite <- unite(VOTOS_PRIMEIROTURNO_UF_2018_2,"ANO_TURNO", ANO_ELEICAO, NUM_TURNO, sep = " -" )

Já a separate que vai fazer o oposto, a partir de uma variável separa em mais variáveis.

separate(banco, variável_criada, into = c(“variável_1”, “variavel_2”“), sep = ” - “)

VOTOS_PRIMEIROTURNO_UF_2018_2_separate <- separate(VOTOS_PRIMEIROTURNO_UF_2018_2_unite, ANO_TURNO, into = c("ANO", "TURNO"), sep = " - ")

Dplyr e seus verbos

Agora que entendemos sobre a estrutura de um banco de dados, vamos começar a explorar as funções que permitem a manipulação de dados. Para isso vamos analisar o banco de dados que originou esse que utilizamos anterior. Nosso objetivo nessas aulas é cpnseguir entender quais a aplicações foram feitas para chegar ao estado das tabelas acima, replicar esse comandos e avançar ainda mais nas possibilidades de manipulação.

Rename

Esse verbo permite renomear uma variável. Então ela se aplica apenas aos nomes das variáveis.

Vamos utilizar o banco que deu origem aos dois primeiros anteriores. Ou seja, é a quantidade de votos obtidas pelos candidatos à presidência em cada estado da federação no primeiro e no segunda turno.

rename(banco, nome_novo = nome_velho)

#Vamos importar o banco completo:

VOTOS_PRESIDENTE_UF_2018 <-read_csv("VOTOS_PRESIDENTE_UF_2018.csv")

# Vamos renomear a variável NUMERO_CANDIDATO

VOTOS_PRESIDENTE_UF_2018_rename <- rename(VOTOS_PRESIDENTE_UF_2018, NUM_CANDIDATO = NUMERO_CANDIDATO)

Select

Essa variável permite a seleção de algumas variáveis entre todas as disponíveis

select(dataframe, variavel_1, variavel_2)

VOTOS_PRESIDENTE_UF_2018_select <- select(VOTOS_PRESIDENTE_UF_2018, ANO_ELEICAO, NUM_TURNO, NUMERO_CANDIDATO, QTDE_VOTOS)

Filter

Se a função select seleciona as variáveis, agora apresentaremos funções que lidam com as observações das variáveis.

filter(dataframe, variavel == “observação”)

Dessa forma, podemos fazer uma tabela que contenha apenas resultado de um estado.

VOTOS_PRESIDENTE_UF_2018_filter1 <- filter(VOTOS_PRESIDENTE_UF_2018, UF == "SP")

Podemos selecionar mais de uma categoria de uma vez usando o sinal de |

VOTOS_PRESIDENTE_UF_2018_filter2 <- filter(VOTOS_PRESIDENTE_UF_2018, UF == "SP"| UF == "RJ"| UF == "ES"| UF == "MG")

E também observações de diferentes categorias. Nesse caso podemos usar ou uma vírgula ou o sinal &.

VOTOS_PRESIDENTE_UF_2018_filter3 <- filter(VOTOS_PRESIDENTE_UF_2018, UF == "SP", NUM_TURNO == 2)

VOTOS_PRESIDENTE_UF_2018_filter3 <- filter(VOTOS_PRESIDENTE_UF_2018, UF == "SP" & NUM_TURNO == 2)

Repare a importância sobre a diferença entre os tipos de variáveis e a forma como são representantas. Quanto temos variáveis de tipo texto, devemos usar aspas, diferente de quando temos números.

Podemos usar o filtro para excluir a variável usando o sinal (!=)

VOTOS_PRESIDENTE_UF_2018_filter4 <- filter(VOTOS_PRESIDENTE_UF_2018, UF != "SP")

A seleção de números é feita de forma um pouco diferente da anterior porque diferente do filtro de variáveis categóricas. Podemos selecionar intervalos de valores com os seguintes operadores: maior (>), maior ou igual (>=), menor (<), menor ou igual (<=).

Vamos selecionar as observações dos estados que obtiveram mais de 1000 votos.

VOTOS_PRESIDENTE_UF_2018_filter5 <- filter(VOTOS_PRESIDENTE_UF_2018, QTDE_VOTOS > 1000)

Mutate + criar uma nova variável

O mutate é o verbo usando amplamente dentro das funções do dyplr já que tem o seu sentido é o de produzir mudanças, como a criação de uma nova variável.

Podemos criar uma variável em branco dessa forma.

VOTOS_PRESIDENTE_UF_2018_nova1 <- mutate(VOTOS_PRESIDENTE_UF_2018, nova_var = NA)

Podemos também copiar uma outra variável e fazer operações com ela para resultar em uma nova.

VOTOS_PRESIDENTE_UF_2018_nova2 <- mutate(VOTOS_PRESIDENTE_UF_2018, nova_var2 = QTDE_VOTOS-1)

Mutate() + ifelse

Podemos preencher algum campo que exija alguma condicionalidade. Assim como vimos no exercício da semana passada.

VOTOS_PRESIDENTE_UF_2018 <- mutate(VOTOS_PRESIDENTE_UF_2018, regiao = ifelse(UF == SP, “SUDESTE”, NA))

Count

A função count() irá contar as categorias de uma variável. Para isso, apresentará os resultados em um dataframe diferendo do dataframe que contém os dados.

Podemos, por exemplo, contar o número de observações por turno.

contar_segundoturno <- count(VOTOS_PRESIDENTE_UF_2018, NUM_TURNO)

group_by() + summarise()

O group_by() e summarise() são funções que trabalham, na maioria das vezes, juntas. Eles servem para sumarizar os dados de acordo com grupos, ou seja, a contagem que haviamos feito com o count() pode ser reproduzida aqui da seguinte forma:

temp_1 <- group_by(VOTOS_PRESIDENTE_UF_2018, UF)
summarise(temp_1, Soma = sum())

O objeto temp_1 é uma tabela agrupada! Visualmente ela parece normal, porém qualquer operação feita nela será realizada de acordo com os grupos nos quais ela encontrou, que neste caso é: MAIOR QUE 40 e MENOR QUE 40.

Quando utilizamos o summarise, iremos agrupar as categorias em torno de uma estatística, no caso, a contagem. Para fazer isso, utilizamos a função n(), uma função utilizada para contar obervações. Caso a variável que fossemos sumarizar fosse númerica, poderiamos utilizar a média (mean()), mediana (median()) e assim por diante.

Portanto, a vantagem do group_by() e summarise() é que conseguimos sumarizar com outras estatísticas além da contagem. Vejamos o exemplo abaixo. Estamos agrupando pela categoria de idade e a cor/raça do candidato. Após isto, estamos contando o número de observações que apresentam estas categorias.

%>%

Até então, vimos os principais verbos do dplyr. Para todas as operações realizadas tivemos que criar diversas linhas de código, salvando várias vezes as saídas dentro de um mesmo objeto, algo que é muito trabalhoso.

O Pipe nos permite uma forma diferente de escrever nossos códigos, permitindo que sejam escritos de forma linear, tornando mais clara a forma de reproduzir uma sequência de tarefas.

Ou seja, o pipe permite que emendemos tarefas.

Imagine que queremos saber a média de votos conquistada pelo candidato Meirelles no primeiro turno por estado. Na nossa tabela final queremos apenas a quantidade de votos e os estados.

Novo_banco <- VOTOS_PRESIDENTE_UF_2018 %>% filter(variável == observação)%>% group_by(variável)%>% summarize(variavel_nova = mean(variavel))%>% select(variavel_1, variavel_2)

Exercícios

1- nova variável com as regiões 2- crie uma nova variável que contenha a porcentagem de votos obtidas por cada candidato (sem votos brancos e nulos) no segundo turno em cada região. Atenção que esse exercício requer que realizemos várias operações antes da realização do cálculo. Tente responder utilizando o pipe