Escolar Documentos
Profissional Documentos
Cultura Documentos
Introdução a Linguagem R
2020
Sumário
Linguagem R e RStudio .................................................................................................................. 4
Introdução ................................................................................................................................. 4
Requisitos .................................................................................................................................. 6
Trabalhando com R ....................................................................................................................... 6
Instalando os Pacotes Básicos ................................................................................................... 6
Começando a Executar Código R .............................................................................................. 7
Visualização de Dados com ggplot2 .......................................................................................... 8
Introdução ............................................................................................................................. 8
O Data Frame mpg ................................................................................................................ 8
Criando seu Primeiro ggplot .................................................................................................. 8
Corrigindo seu Código ......................................................................................................... 11
O Básico de Programação ....................................................................................................... 11
Nomes de Objetos ............................................................................................................... 12
Chamando Funções ............................................................................................................. 13
Transformação de Dados com dplyr ....................................................................................... 14
Introdução ........................................................................................................................... 14
O Básico do dplyr................................................................................................................. 15
Filtrar Linhas com filter() ..................................................................................................... 15
Comparações........................................................................................................................... 16
Operadores Lógicos ................................................................................................................. 17
Valores Faltantes ..................................................................................................................... 18
Ordenar Linhas ........................................................................................................................ 19
Selecionar Colunas .................................................................................................................. 19
Adicionando Novas Variáveis .................................................................................................. 21
Funções de Criação Úteis ........................................................................................................ 23
Agregados cumulativos e móveis ........................................................................................ 23
Resumos Agrupados ................................................................................................................ 25
Combinando múltiplas operações com o pipe........................................................................ 26
Valores Faltantes ................................................................................................................. 27
Contagem ............................................................................................................................ 28
Funções Resumo ................................................................................................................. 30
Agrupamento por múltiplas variáveis ................................................................................. 34
Desagrupar .......................................................................................................................... 35
Esta apostila introdutória pode conter erros, falhas ou imprecisões. Se você identificar algum problema
por favor informe através do e-mail vidal@usp.br para que a correção possa ser providenciada.
Esta apostila não é autoral, tem objetivo estritamente didático como material de apoio para a disciplina.
Foi desenvolvida através da compilação dos diversos textos e materiais citados na bibliografia.
Obrigado!
Linguagem R e RStudio
Introdução
A linguagem R é uma linguagem de programação e ambiente de software aberto voltado para análise
estatística e computacional de dados, geração de gráficos e relatórios. Foi criada em 1998 por Ross Ihaka
e Robert Gentleman na Universidade de Auckland, Nova Zelândia, e é atualmente desenvolvida pelo “R
Development Core Team”, além de contar com a contribuição de uma grande comunidade de cientistas
de dados.
Desde 2004 a linguagem R é disponibilizada gratuitamente sob a modalidade de licença pública GNU,
sendo hoje fornecida para diversos sistemas operacionais, como Linux, Windows e Mac, além de ser
embarcada em várias plataformas de análise de dados.
Seu nome origina-se da primeira letra do nome de seus dois autores originais (Robert Gentleman and
Ross Ihaka), e talvez também devido a uma brincadeira que ambos fizeram com o nome da linguagem S
da Bell Labs na qual se basearam para a criação do R.
A linguagem R é na verdade um conjunto integrado de software para manipulação de dados, cálculo e
exibição gráfica. Entre outras coisas oferece:
1. Uma solução eficaz de manuseio e armazenamento de dados,
2. Um conjunto de operadores para cálculos em conjuntos de dados, em particular matrizes,
3. Uma grande, coerente e integrada coleção de ferramentas para análise de dados,
4. Recursos gráficos para análise de dados e exibição diretamente no computador, e
5. Uma linguagem de programação bem desenvolvida, simples e eficaz que inclui expressões
condicionais, loops, funções recursivas definidas pelo usuário e recursos para leitura e gravação
de arquivos de dados.
Portanto, R pode ser considerado um ambiente com uma implementação da linguagem S que foi
desenvolvida nos Laboratórios Bell por Rick Becker, John Chambers e Allan Wilks.
O termo "ambiente" pretende caracterizar a linguagem R como um sistema totalmente planejado e
coerente, em vez de um agregado incremental de ferramentas muito específicas e inflexíveis, como ocorre
frequentemente com outras ferramentas de software para análise de dados.
A linguagem R é um meio para aplicar métodos recém-desenvolvidos de análise interativa de dados.
Evoluiu rapidamente e foi estendido por uma grande coleção de pacotes. No entanto, a maioria dos
programas escritos em R são essencialmente efêmeros, escritos para uma única e específica análise de
dados.
Muitas pessoas usam o R como sistema estatístico. Preferimos pensar nele como um ambiente no qual
muitas técnicas estatísticas clássicas e modernas foram implementadas. Algumas delas são incorporadas
no ambiente R base, mas a maioria são fornecidas como pacotes. Existem cerca de 25 pacotes fornecidos
com R (chamados pacotes "padrão" e "recomendados") e muitos mais estão disponíveis através da família
CRAN de sites da Internet (via https://CRAN.R-project.org) e em outros lugares.
Para baixar a linguagem R e instalar em seu computador, vá ao CRAN, a rede de distribuição do R (em
inglês Comprehensive R Arquive Network). O CRAN é composto por um conjunto de servidores-espelho
distribuídos pelo mundo (há um na USP) e é usado para distribuir a linguagem R e os pacotes ou bibliotecas
de R. Não é necessário escolher um servidor perto de você, em vez disso, use o espelho em nuvem do link
abaixo pois ele descobre automaticamente para você.
depurar e gerenciar o seu espaço de trabalho em R. Saiba mais sobre os recursos do RStudio em
https://www.rstudio.com/products/rstudio/features/ .
Tanto o R como o RStudio são periodicamente atualizados (cerca de duas vezes por ano). Quando uma
nova versão estiver disponível, você provavelmente será avisado. É recomendável fazer a atualização
regularmente, porém, especialmente quanto ao R, pode ocorrer que alguns pacotes não estejam
disponíveis ou inicialmente não funcionem numa nova versão. Por esse motivo é prudente consultar a
documentação dos pacotes que você estiver utilizando antes de fazer uma atualização do R.
Nesta apostila utilizaremos a versão 3.6.3 do R e a versão 1.3.959 do RStudio. Recomendamos que você
procure instalar e utilizar estas mesmas versões no seu equipamento.
Após instalar o RStudio em seu computador, acione-o simplesmente localizando-o no menu iniciar do
Windows e clicando o seu ícone:
Você será apresentado ao console do RStudio, conforme ilustra a figura a seguir. Inicialmente faça um
passeio pelas seguintes janelas do RStudio, resumidamente descritas a seguir:
• Console: onde você digita instruções utilizando a sintaxe da linguagem R e recebe os resultados
de sua execução;
• Environment: onde você poderá visualizar e consultar o seu espaço de trabalho, que apresentará
os conjuntos de dados utilizados para análise, variáveis e valores de resultados das operações
realizadas.
• History: onde você poderá consultar e visualizar todo o histórico de instruções executadas e
operações realizadas.
• Files: onde você poderá consultar arquivos e pastas do seu espaço de trabalho. Durante a
instalação do RStudio, uma pasta denominada R, é automaticamente criada no seu ambiente de
usuário Windows.
• Plots: onde você poderá consultar os resultados gráficos das operações realizadas.
Particularmente neste laboratório, será onde visualizaremos as redes neurais construídas com
seus respectivos neurônios.
• Packages: onde você poderá consultar e instalar os pacotes da linguagem R. Os pacotes contém
bibliotecas de rotinas e constituem o verdadeiro “poder” do R, pois são gratuitos, construídos
por uma comunidade mundial de cientistas de dados e avalizados pelos mantenedores da
linguagem R. Atendem a praticamente qualquer necessidade de análise de dados e estão em
constante evolução. Os pacotes estão disponíveis através da Internet, portanto, para instalá-los
em seu espaço de trabalho você precisará ter acesso à Internet.
• Help: a partir de onde você poderá aprender “tudo” sobre a linguagem R e começar a se tornar
um “cientista de dados”.
• Viewer: onde você poderá visualizar resultados e objetos, dependendo dos pacotes R que estiver
utilizando.
Requisitos
A linguagem R é muito extensa e a comunidade que a desenvolve, apoia e utiliza está continuamente
agregando novos recursos e algoritmos através dos pacotes. Neste laboratório utilizaremos apenas uma
pequena parte dos recursos e possibilidades analíticas da linguagem R.
Verifique se os seguintes itens estão instalados no seu sistema:
• R versão 3.6.3 ou versão mais recente
• RStudio 1.3.959 ou versão mais recente.
Novamente lembramos que para trabalhar com a linguagem R é necessário estar conectado na Internet,
uma vez que todos os seus “pacotes” ou bibliotecas de recursos são acessíveis pela Web e você sempre
acabará precisando de uma que ainda não está instalada no seu computador.
Trabalhando com R
Instalando os Pacotes Básicos
Inicialmente você precisará instalar, através do RStudio, alguns pacotes essenciais do R. Um pacote R é
uma coleção de funções, dados e documentação que estende as capacidades do R básico. Usar pacotes é
a chave para o uso bem sucedido de R e Python.
O primeiro pacote que instalaremos é o “tidyverse” que na verdade contém um conjunto de outros
pacotes que foram projetados para trabalhar em conjunto e possuem muitas funções.
Para instalá-lo digite a instrução a seguir na janela console do RStudio e tecle [Enter] para executá-la.
Estando conectado à Internet o R fará o download dos pacotes do CRAN e os instalará localmente no seu
computador. Esse mesmo procedimento ocorrerá com qualquer pacote que você instalar.
install.packages("tidyverse")
Para utilizar qualquer pacote, mesmo os que tiverem sido previamente instalados, você precisa carrega-
los na memória de trabalho do R através da instrução library(), conforme a seguir. Note como o RStudio
o ajuda sugerindo para você as instruções e pacotes a serem digitados.
library(tidyverse)
Note que o pacote tidyverse carrega na memória de trabalho do R diversos pacotes, conforme ilustrado
na figura anterior. Os pacotes do tidyverse são atualizados com bastante frequência. Você pode atualizar
os pacotes instalados através da janela “Packages” do RStudio, que mostra os principais pacotes
disponíveis e os instalados no seu computador, clicando o botão [Update], conforme ilustra a figura
anterior.
À medida que você desenvolver novos projetos de análise de dados com o R, você aprenderá e utilizará
novos pacotes e novas maneiras de pensar e analisar dados. Esta é uma das principais características das
linguagens de análise de dados como o R e Python, você sempre irá evoluir e aprender através de novos
pacotes, desenvolvidos gratuitamente por uma comunidade mundial de cientistas de dados. Quem sabe,
no futuro, você também não venha a contribuir com eles?
Esta apostila obviamente não é uma ilha e tampouco pretende abranger a maior parte dos recursos do R,
uma vez que todos é simplesmente impossível para qualquer um. À medida que você começar a conhecer
o R para aplicá-lo à análise dos seus dados, precisará buscar mais conhecimento. Comece com o Google e
tenha em mente que a mesma dificuldade, problema, dúvida ou necessidade de que você está tendo
alguém também muito provavelmente já teve e o Google encontrará este conhecimento para você utilizar
e expandir o seu.
O objetivo desta apostila é o de que você conheça as ferramentas básicas do R para exploração de dados
o mais rápido possível. A exploração de dados é a arte e a ciência de observar seus dados, gerar hipóteses
e testá-las com rapidez e repetir, repetir e repetir. O objetivo é, portanto, gerar muitas oportunidades
promissoras para análise que você poderá explorar mais tarde com mais profundidade para alcançar seus
objetivos.
A visualização de dados é um ótimo assunto para começar com a programação em R, porque a
recompensa é muito clara: você pode fazer gráficos elegantes e informativos que o ajudarão a entender
seus dados.
Desta forma, nesta apostila você aprenderá a estrutura básica de um gráfico ggplot2 e técnicas para
transformar dados em gráficos úteis. Porém só a visualização não será o suficiente, então você também
aprenderá as instruções-chave que lhe permitirão selecionar variáveis importantes, filtrar observações,
criar variáveis e calcular resumos. Finalmente, você combinará a visualização com a transformação de
dados para responder perguntas interessantes sobre os dados.
Embora a modelagem também seja parte do processo de exploração de dados, será abordada em outros
cursos.
Lembre-se, você só precisa instalar um pacote uma vez com install.packages(), mas precisa carrega-lo
toda vez que for utilizá-lo com library(), conforme executado.
O gráfico mostra uma relação inversa entre o tamanho do motor (displ) e a eficiência do combustível
(hwy). Automóveis com motores maiores tem menos eficiência, isto é, utilizam mais combustível.
Como o ggplot2 funciona:
1. O primeiro argumento define o conjunto de dados a ser utilizado para construir o gráfico: data =
mpg;
2. A função geom_point() adiciona uma camada de pontos ao seu gráfico, que cria um gráfico de
dispersão. Há muitas funções geom que adicionam tipos diferentes de gráficos;
3. O argumento mapping define as variáveis do conjunto de dados que serão mapeadas para o
gráfico.
4. Ele sempre é combinado com aes(), e os argumentos x e y de aes() especificam quais variáveis
mapear para os eixos x e y;
Portanto, para fazer um gráfico com o ggplot2 você deve substituir os argumentos entre colchetes
angulares por um conjunto de dados (mpg no exemplo), uma função geom (geom_point() no exemplo) e
uma coleção de mapeamentos (aes(x = displ, y = hwy) no exemplo).
ggplot(data = <DATA>) + <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
Você pode adicionar uma terceira variável, como class, no seu gráfico de dispersão bidimensional e
mapeá-la para uma “estética” (aesthetic). Uma estética é uma propriedade visual dos objetos em seu
gráfico. Incluem estéticas como tamanho, forma ou cor dos seus pontos. Por exemplo, você pode mapear
as cores dos seus pontos para a variável class de forma a revelar simultaneamente a classe de cada
automóvel no seu gráfico:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))
Podemos alternativamente mapear class para a estética de tamanho da mesma maneira. Neste caso, o
tamanho de cada ponto, e não mais a cor, refletirá a classe do automóvel.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))
Recebemos uma advertência aqui pois mapear uma variável não ordenada (class) para uma estética
ordenada (size) não é uma boa ideia, mas neste caso parece até razoável.
Você também pode configurar as propriedades de sua geom manualmente. Por exemplo, podemos deixar
todos os pontos do nosso gráfico em azul (blue).
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
O Básico de Programação
Agora você já tem alguma experiência executando código R. Não demos muitos detalhes, mas você
obviamente descobriu o básico. A frustração é natural quando você começa a programar, mas essa
sensação acontece com todos, e a única maneira de superar isso é continuar tentando.
Antes de irmos mais longe, vamos ter certeza de que você tem uma base sólida na execução do código R,
e que você sabe sobre alguns dos recursos RStudio mais úteis.
Vamos rever alguns fundamentos que até agora omitimos no interesse de fazer você se apaixonar pelo R
o mais rápido possível. Você pode usar R como calculadora, experimente:
1 / 200 * 30
(59 + 73 + 2) / 3
sin(pi / 2)
Todas as instruções R onde você cria objetos, declarações de atribuição, têm a mesma forma:
nome_objeto <- valor
Nomes de Objetos
Os nomes dos objetos devem começar com uma letra e só podem conter letras, números, '_' e '.'. Se você
quiser que seus nomes de objeto sejam descritivos, então precisará de uma convenção para várias
palavras. Recomendo separar palavras minúsculas com '_' ou utilizar as técnicas abaixo:
1. i_use_snake_case
2. otherPeopleUseCamelCase
3. some.people.use.periods
4. And_aFew.People_RENOUNCEconvention
Você pode inspecionar um objeto digitando seu nome:
x <- 10
x
Para inspecionar este objeto, experimente os recursos do RStudio: digite "este", pressione [Tab], adicione
caracteres até que você tenha um resultado único e pressione o [Enter].
Ooops, você cometeu um erro! 'este_e_um_nome_realmente_longo' deve ter valor 3.5 e não 2.5. Use
outro atalho de teclado para ajudá-lo a corrigi-lo. Digite "este" e pressione [Ctrl + ↑]. Isso listará todos
os comandos que você digitou que iniciam essas letras. Use as teclas de seta para navegar e pressione
[Enter] para redigitar o comando. Mude de 2,5 para 3,5 e execute novamente.
Há um contrato implícito entre você e o R: ele fará cálculo complexo e tedioso para você, mas em troca,
você deve ser completamente preciso em suas instruções. Erros de digitação importam. Maiúsculas e
minúsculas importam, pois para o R são diferentes.
Chamando Funções
R tem uma grande coleção de funções incorporadas que são chamadas assim:
função_nome(arg1 = val1, arg2 = val2, ...)
Vamos tentar usar a função 'seq()' que gera sequencias regulares de números e, enquanto isso, aprender
características úteis do RStudio. Digite 'se' e aperte [Tab]. Um pop-up mostra possíveis conclusões.
Especifique 'seq()' digitando mais (um "q") para desam biguar, ou usando setas ↑/・ para
selecionar. Observe a dica flutuante que aparece, lembrando-o dos argumentos e propósitos da função.
Se você quiser mais ajuda, pressione a F1 para obter todos os detalhes na guia de ajuda na janela inferior
direita.
Pressione [Tab] mais uma vez quando você selecionar a função desejada. O RStudio adicionará parênteses
de abertura ('(') e fechamento (')') para você. Digite os argumentos '1, 10' e aperte o retorno.
seq(1, 10)
Digite este código e observe que você recebe assistência semelhante com as aspas emparelhadas:
x <- "Olá mundo"
Aspas e parênteses devem sempre vir em um par. RStudio faz o seu melhor para ajudá-lo, mas ainda é
possível estragar tudo e acabar com uma incompatibilidade. Se isso acontecer, o R mostrará o caractere
de continuação "+":
x <- "Olá pessoal
+
O '+' diz que o R está esperando por mais alguma instrução; ele não acha que você a completou ainda.
Normalmente isso significa que você esqueceu um ''' ou um '''. Adicione o par faltando ou pressione [Esc]
para abortar a expressão e tentar novamente.
Se você fizer uma atribuição, não poderá ver o valor. Você é então tentado a verificar imediatamente o
resultado:
y <- seq(1, 10, length.out = 5)
y
Essa ação comum pode ser encurtada ao cercar a tarefa com parênteses, o que faz com que a atribuição
e a "impressão para a tela" aconteçam simultaneamente.
(y <- seq(1, 10, length.out = 5))
Para ver este conjunto de dados, você pode executar 'View(flights)' para abri-los na janela do visualizador
do RStudio, conforme ilustra a próxima figura.
view(flights)
Você também deve ter notado a linha de três (ou quatro) abreviaturas de letras sob os nomes das colunas.
Estes descrevem o tipo de cada variável:
• int significa inteiros.
• dbl significa duplos, ou números reais.
• chr significa vetores de caracteres, ou strings.
• dttm significa data-hora (uma data + uma hora).
• lgl significa vetores lógicos que contêm apenas 'TRUE' ou 'FALSE'.
• fctr significa fatores, que R usa para representar variáveis categóricas com valores fixos possíveis.
• date significa datas.
O Básico do dplyr
Neste tópico, estudaremos as cinco funções principais do dplyr que permitem resolver muitos desafios
de manipulação de dados:
• Filtrar observações por seus valores com filter().
• Organizar as linhas com arrange().
• Selecionar variáveis por seus nomes com select().
• Criar novas variáveis com funções de variáveis existentes com mutate().
• Agregar muitos valores em um único resumo com summarise().
Todas estas funções podem ser usadas em conjunto com group_by() que altera o escopo de cada função
de operação em todo o conjunto de dados para operar grupo por grupo. Essas seis funções fornecem os
comandos para uma linguagem de manipulação de dados.
Todos os comandos funcionam da mesma forma:
1. O primeiro argumento é um data frame (conjunto tabular de dados).
2. Os argumentos subsequentes descrevem o que fazer com o data frame, utilizando os nomes de
variável (sem aspas).
3. O resultado é um novo data frame.
Juntas, essas propriedades facilitam o encadeamento de vários passos simples para alcançar um resultado
complexo.
Quando você executa essa linha de código, o dplyr executa a operação de filtragem e retorna um novo
data frame. As funções dplyr nunca modificam suas entradas, então se você quiser salvar o resultado em
um novo data frame, você precisará usar o operador de atribuição, '<-':
mar8 <- filter(flights, month == 3, day == 8)
O R imprime os resultados ou os salva a uma variável. Se você quiser fazer as duas coisas, pode envolver
a tarefa entre parênteses:
(dec25 <- filter(flights, month == 12, day == 25))
Comparações
Para usar a filtragem de forma eficaz, você precisa saber como selecionar as observações que deseja
usando os operadores de comparação. O R fornece o conjunto padrão: '>', '>=', '<', '<=', '!=' (não igual) e
'==' (igual).
Quando você está começando com R, o erro mais comum de cometer é usar '=' em vez de '==' ao testar a
igualdade. Quando isso acontecer, você obterá um erro informativo:
filter(flights, month = 1)
Há outro problema comum que você pode encontrar ao usar '==': números de pontos flutuantes. Esses
resultados podem surpreendê-lo!
sqrt(2) ^ 2 == 2
[1] FALSE
1 / 49 * 49 == 1
[1] FALSE
Os computadores usam aritmética de precisão finita (eles obviamente não podem armazenar um número
infinito de dígitos) então lembre-se que cada número que você vê é uma aproximação. Nestes casos, em
vez de utilizar '==', utilize 'near()':
near(sqrt(2) ^ 2, 2)
[1] TRUE
near(1 / 49 * 49, 1)
[1] TRUE
Operadores Lógicos
Vários argumentos para 'filter()' são combinados com "and": toda expressão deve ser verdadeira para que
uma linha seja incluída na saída. Para outros tipos de combinações, você mesmo precisará usar
operadores booleanos: '&' é "and", '|' é "or", e '!' é "not". A figura a seguir mostra o conjunto completo
de operações booleanas (lógicas falso ou verdadeiro).
O código a seguir utiliza o operador “or” “|” para encontrar todos os voos que partiram em novembro ou
dezembro:
filter(flights, month == 11 | month == 12)
Cuidado, não se pode escrever 'filter(flights, month == (11 | 12))', que você pode literalmente traduzir em
"encontrar todos os voos que partiram em novembro ou dezembro". Em vez disso, o R encontra todos os
meses que são iguais a ‘11 | 12’, expressão que é avaliada como 'TRUE'. Em um contexto numérico (como
aqui), 'TRUE' se torna 1, então isso encontrará todos os voos em janeiro, e não em novembro ou
dezembro. Isso é um pouco confuso, mas é o que ocorre!
Uma solução para este problema é 'x %in% y'. Isso selecionará cada linha onde 'x' é um dos valores em 'y'.
Poderíamos usá-lo para reescrever o código acima, experimente e veja o resultado.
nov_dec <- filter(flights, month %in% c(11, 12))
Às vezes você pode simplificar uma expressão complicada lembrando que '! (x & y)' é o mesmo que '!x |
!y', e '! (x | y)' é o mesmo que '!x & !y'. Se você quiser encontrar voos que não estavam atrasados (na
chegada ou partida) por mais de duas horas, você poderia usar qualquer um dos dois filtros a seguir:
filter(flights, !(arr_delay > 120 | dep_delay > 120))
filter(flights, arr_delay <= 120, dep_delay <= 120)
Além de '&' e '|', o R também tem '&&' e '|| `. Aqui eles não devem ser utilizados, mas você aprenderá
quando e como deve usá-los em execução condicional.
Sempre que você começar a usar expressões complicadas e multipartes em 'filter()', considere torná-las
variáveis explícitas. Isso torna muito mais fácil verificar o seu trabalho. Você aprenderá a criar variáveis
em breve.
Valores Faltantes
Uma característica importante do R que pode tornar a comparação complicada são os valores ausentes,
ou 'NA's ("não disponíveis" ou “not available”). Como 'NA' representa um valor desconhecido, os valores
ausentes são "contagiosos", ou seja, quase qualquer operação envolvendo um valor desconhecido
também gerará um resultado desconhecido.
NA > 5
10 == NA
NA + 10
NA / 2
[1] TRUE
'filter()' inclui apenas linhas onde a condição é 'TRUE'; exclui os valores 'FALSE' e 'NA'. Se você quiser
preservar os valores ausentes, deve pedir explicitamente como exemplificado a seguir, onde a função
tibble cria um data frame:
df <- tibble(x = c(1, NA, 3))
df
filter(df, x > 1)
filter(df, is.na(x) | x > 1)
Exercícios
1. Encontre todos os voos que
a. Tiveram um atraso de chegada de duas ou mais horas
b. Voou para Houston ('IAH' ou 'HOU')
Ordenar Linhas
A função 'arrange()' opera de forma semelhante a 'filter()' exceto que, em vez de selecionar linhas, ela
altera sua ordem. É preciso um data frame e um conjunto de nomes de coluna (ou expressões mais
complicadas) pelas quais a ordenação será efetuada. Se você fornecer mais de um nome de coluna, cada
coluna adicional será usada para desempatar a ordenação dos valores das colunas anteriores:
Você pode usar 'desc()' para reordenar por uma coluna em ordem descendente:
view(arrange(flights, desc(dep_delay)))
Exercícios
1. Ordene ‘flights’ para mostrar os voos mais atrasados.
2. Ordene 'flights' para encontrar os voos mais rápidos (de maior velocidade).
3. Quais voos foram os mais distantes? Qual foi o menos distante?
Selecionar Colunas
Não é raro obteremos conjuntos de dados com centenas ou mesmo milhares de variáveis. Neste caso, o
primeiro desafio é, muitas vezes, concentrar-se nas variáveis em que você está realmente interessado. A
função 'select()' permite que você selecione rapidamente um subconjunto útil usando operações
baseadas nos nomes das variáveis.
A função 'select()' não será muito útil com os dados dos voos porque temos apenas 19 variáveis, mas você
ainda pode ter a ideia geral do seu funcionamento:
Existem várias funções de auxiliares que você pode usar dentro de 'select()':
• `starts_with("abc")`: seleciona nomes que começam com "abc".
• `ends_with("xyz")`: seleciona nomes que terminam com "xyz".
• `contains("ijk")`: seleciona nomes que contêm "ijk".
• `matches("(.)\\1")`: seleciona variáveis que correspondem a uma expressão regular. Esta
corresponde a quaisquer variáveis que contenham caracteres repetidos. Você aprenderá sobre
expressões regulares em [strings].
• `num_range("x", 1:3)`: seleciona colunas com 'x1', 'x2' e 'x3'.
Consulte '?select' diretamente no RStudio para obter mais detalhes.
A função 'select()' pode ser usada para renomear variáveis, mas raramente é útil porque exclui todas as
variáveis não explicitamente mencionadas. Para renomear variáveis recomendamos que você use
'rename()', que é uma variante de 'select()' que mantém todas as variáveis que não são explicitamente
mencionadas:
rename(flights, tail_num = tailnum)
Outra opção é usar 'select()' em conjunto com a função 'everything()'. Isso será útil se você tiver um
conjunto de variáveis que você gostaria de mover para o início do data frame.
select(flights, time_hour, air_time, everything())
Exercícios
1. Descubra o que acontece se você incluir o nome de uma variável várias vezes em uma chamada
'select()'.
2. Descubra o que faz a função auxiliar 'one_of()'? Por que pode ser útil em conjunto com o vetor de
nomes de variáveis abaixo?
Na instrução a seguir, c() é uma função genérica que combina seus argumentos em um vetor.
vars <- c("year", "month", "day", "dep_delay", "arr_delay")
3. Descubra como utilizar select() para selecionar apenas as variáveis ou colunas do data frame flights
que possuem ‘time’ em se nome.
Observe que você pode consultar colunas que você acabou de criar:
mutate(flights_sml,
gain = dep_delay - arr_delay,
hours = air_time / 60,
gain_per_hour = gain / hours
)
Se você precisar de agregados móveis (ou seja, uma soma calculada sobre uma janela móvel),
experimente o pacote RcppRoll.
install.packages("RcppRoll")
library(RcppRoll)
x
roll_sum(x, 5)
roll_mean(x, 5)
Se 'min_rank()' não fizer o que você precisa, olhe para as variantes 'row_number()', 'dense_rank()',
'percent_rank()', 'cume_dist()', 'ntile()'. Consulte suas respectivas páginas de ajuda para obter mais
detalhes.
row_number(y)
dense_rank(y)
percent_rank(y)
cume_dist(y)
Exercícios
Experimente estes novos conhecimentos e interprete os resultados e gráficos obtidos executando as
instruções a seguir:
flights <- flights %>% mutate(
dep_time = hour * 60 + minute,
arr_time = (arr_time %/% 100) * 60 + (arr_time %% 100),
airtime2 = arr_time - dep_time,
dep_sched = dep_time + dep_delay
)
Resumos Agrupados
O último comando chave é 'summarise()'. Ele colapsa um data frame para uma única linha:
summarise(flights, delay = mean(dep_delay, na.rm = TRUE))
Juntos 'group_by()' e 'summarise()' fornecem uma das ferramentas que você usará mais comumente ao
trabalhar com dplyr: resumos agrupados.
Analisando os dados obtidos, parece que os atrasos aumentam com a distância até ~750 milhas e depois
diminuem. Talvez à medida que os voos ficam mais longos, possa haver mais capacidade de compensar
atrasos no ar. Porém, você pode observar mais facilmente isso no gráfico a seguir.
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
geom_point(aes(size = count), alpha = 1/3) +
geom_smooth(se = FALSE)
Este código é um pouco frustrante de escrever porque temos que dar a cada conjunto de dados
intermediário um nome, mesmo que não nos importemos com ele. Nomear coisas é difícil, então isso
atrasa nossa análise.
Porém, há outra maneira de resolver o mesmo problema utilizando o pipe, '%>%':
delays <- flights %>%
group_by(dest) %>%
summarise(
count = n(),
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
) %>%
filter(count > 20, dest != "HNL")
Isso se concentra nas transformações, não no que está sendo transformado, o que torna o código mais
fácil de ler. Você pode lê-lo como uma série de declarações imperativas: agrupar, em seguida, sumarizar,
em seguida, filtrar. Uma boa maneira de interpretar '%>%' ao ler código é traduzindo para "depois".
Nos bastidores, 'x %>% f(y)' se transforma em 'f(x, y)', e 'x %>% f(y) %>% g(z)' se transforma em 'g(f(x, y),
z)' e assim por diante. Você pode usar o pipe para reescrever várias operações de uma maneira que você
pode ler da esquerda para a direita, de cima para baixo. Usaremos pipe com frequência a partir de agora
porque melhora consideravelmente a legibilidade do código, e oportunamente voltaremos a ele com mais
detalhes.
Valores Faltantes
Você deve ter se perguntado sobre o argumento "na.rm" que usamos antes. O que acontece se não o
definirmos?
flights %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay))
Como você pode ver na figura a seguir, temos muitos valores faltando em nosso data frame. Isso porque
as funções de agregação obedecem à regra usual de valores ausentes: se houver algum valor faltando na
entrada, a saída será um valor faltando. Felizmente, todas as funções de agregação têm um argumento
'na.rm' que remove os valores faltantes antes da sua computação:
flights %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay, na.rm = TRUE))
Neste caso, onde os valores ausentes representam voos cancelados, também poderíamos resolver o
problema removendo primeiro os voos cancelados. Vamos salvar este conjunto de dados para que
possamos reutilizá-lo nos próximos exemplos.
not_cancelled <- flights %>%
filter(!is.na(dep_delay), !is.na(arr_delay))
not_cancelled %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay))
Contagem
Sempre que você fizer qualquer agregação, é uma boa ideia incluir uma contagem ('n()'), ou uma
contagem de valores não faltantes ('sum(!is.na(x)'). Dessa forma, você pode verificar se você não está
tirando conclusões com base em quantidades muito pequenas de dados. Por exemplo, vamos olhar para
as aeronaves (identificadas pelo número da cauda) que têm os maiores atrasos médios:
Como quase sempre acontece, é mais fácil e melhor analisar o resultado através de um gráfico:
ggplot(data = delays, mapping = aes(x = delay)) +
geom_freqpoly(binwidth = 10)
Parece que há algumas aeronaves que têm um atraso médio de 5 horas (300 minutos). Parece um exagero,
mas como seria possível explicar isso? Esta análise precisa ser feita com calma. Podemos obter mais
informações se desenharmos uma dispersão de número de voos versus seu atraso médio, conforme a
seguir:
delays <- not_cancelled %>%
group_by(tailnum) %>%
summarise(delay = mean(arr_delay, na.rm = TRUE), n = n() )
ggplot(data = delays, mapping = aes(x = n, y = delay)) +
geom_point(alpha = 1/10)
Não devemos nos surpreender ao constatar que há uma variação maior no atraso médio quando há
menos voos. A forma deste gráfico é muito característica: sempre que você traçar uma média (ou outro
resumo) versus o tamanho do grupo, perceberá que a variação diminui à medida que o tamanho da
amostra aumenta.
Portanto, ao observar este tipo de gráfico, muitas vezes é útil filtrar os grupos que possuem menor
número de observações, para que você possa ver mais o padrão e menos a variação extrema que tende a
ocorrer nos menores grupos. Isso é o que o código a seguir faz, considerando n > 25, além de mostrar-lhe
um padrão útil para integrar ggplot2 em fluxos dplyr. É um pouco complicado que você tenha que mudar
de '%>%' para '+', mas uma vez que você pegar jeito, verá que é bastante conveniente.
delays %>%
filter(n > 25) %>%
ggplot(mapping = aes(x = n, y = delay)) +
geom_point(alpha = 1/10)
Como você pode observar no gráfico resultante, eliminando os grupos com um número muito pequeno
de casos os extremos do atraso médio caem de 300 para aproximadamente 40 minutos, o que parece
bem mais razoável. O que fizemos foi eliminar os dados extremos, ou seja, os voos com atraso exagerado,
ou fora do padrão esperado (fora da curva ou outlier), que normalmente são poucos, focar nossa análise
na maior parte dos casos. Com isso obtivemos um valor médio de atraso em torno de 40 minutos, o que
parece bem mais razoável. Provavelmente os casos com atrasos de até 5 horas podem estar relacionados
a problemas meteorológicos, fechamento de aeroporto, problemas mecânicos na aeronave ou
equivalentes. Estes casos precisariam ser investigados, portanto, individualmente, pois fogem do padrão.
Funções Resumo
Utilizar apenas médias, contagens e somas pode ser muito útil em suas análises, mas certamente não será
suficiente para explicar ou descobrir problemas mais complexos que fogem ao bom senso como o
exemplo anterior. Felizmente o R fornece muitas outras funções resumo extremamente úteis para ajudá-
lo a sofisticar suas análises:
Medidas de localização: median()
Nós usamos a média 'mean(x)', mas a mediana 'median(x)' também é útil. A média é a soma dividida pelo
comprimento; a mediana é um valor de posição, onde 50% de 'x' está acima dele, e 50% está abaixo dele.
Às vezes também é útil combinar agregação com subconjuntos lógicos, como exemplificado a seguir, onde
separamos dois conjuntos de atrasos, o geral (1) e os atrasos apenas positivos (2) dos voos que não foram
cancelados.
not_cancelled %>%
group_by(year, month, day) %>%
summarise(
avg_delay1 = mean(arr_delay),
avg_delay2 = mean(arr_delay[arr_delay > 0]))
# delay1: o atraso geral médio
# delay2: o atraso positivo médio
Essas funções são complementares à filtragem de classificação. A filtragem fornece todas as variáveis,
com cada observação em uma linha separada:
not_cancelled %>%
group_by(year, month, day) %>%
mutate(r = min_rank(desc(dep_time))) %>%
filter(r %in% range(r))
Contagem
Você já viu 'n()', que não tem argumentos, e retorna o tamanho do grupo atual. Para contar o número de
valores não faltantes, você pode utilizar 'sum(!is.na(x))'. Para contar o número de valores distintos
(únicos), você pode utilizar 'n_distinct(x)'.
Quais destinos têm mais companhias aéreas?
not_cancelled %>%
group_by(dest) %>%
summarise(carriers = n_distinct(carrier)) %>%
arrange(desc(carriers))
As contagens são tão úteis que o dplyr fornece uma função auxiliar simples caso tudo o que você quiser
fazer seja uma contagem:
not_cancelled %>%
count(dest)
Tenha cuidado ao progressivamente calcular resumos: não há problema em somas e contagens, mas você
precisa pensar em médias e variações de ponderação, e não é possível fazê-lo exatamente para
estatísticas baseadas em classificação, como a mediana. Em outras palavras, a soma das somas agrupadas
é a soma geral, mas a mediana das medianas agrupadas não é a mediana geral.
Desagrupar
Se você precisar remover o agrupamento e retornar às operações em dados não agrupados, use
'ungroup()'.
daily %>%
ungroup() %>% # não mais agrupado por data
summarise(flights = n()) # todos os voos
Exercícios
1. Brainstorm pelo menos 5 maneiras diferentes de avaliar as características típicas de atraso de um
grupo de voos. Considere os seguintes cenários:
• Um voo é 15 minutos adiantado em 50% do tempo, e 15 minutos atrasado 50% do tempo.
• Um voo está sempre 10 minutos atrasado.
• Um voo é 30 minutos adiantado em 50% do tempo, e 30 minutos atrasado 50% do tempo.
• 99% das vezes que um voo é pontual. 1% das vezes é 2 horas atrasado.
• O que é mais importante: atraso de chegada ou atraso na partida?
2. Veja o número de voos cancelados por dia. Existe um padrão? A proporção de voos cancelados está
relacionada ao atraso médio?
3. Qual companhia aérea tem os piores atrasos? Desafio: você conseguiria discriminar os efeitos de
aeroportos ruins versus companhias ruins? (Dica: pense em `flights %>% group_by(carrier, dest) %>%
summarise(n())`)
4. O que faz o argumento 'sort' em count()'. Quando você pode usá-lo?
Encontre todos os grupos maiores que um limiar, por exemplo, os destinos mais populares:
popular_dests <- flights %>%
group_by(dest) %>%
filter(n() > 365)
popular_dests
Um filtro agrupado é uma mudança agrupada seguida por um filtro não agrupado, mas é difícil verificar
se você fez a manipulação corretamente.
Exercícios
1. Descubra qual aeronave ('tailnum') tem o pior registro de pontualidade?
2. Descubra que hora do dia você deve voar se quiser evitar atrasos?
3. Para cada destino, calcule os minutos totais de atraso. Para cada voo, calcule a proporção do atraso
total para o seu destino.
4. Olhe para cada destino. Você pode encontrar voos que são rápidos demais, ou seja, voos que
representam um possível erro de entrada de dados.
5. Calcule o tempo de viagem de um voo em relação ao voo mais curto para esse destino. Quais voos
ficaram mais atrasados no ar?
6. Encontre todos os destinos que são atendidos por pelo menos duas companhias. Use essas
informações para classificar as companhias.
7. Para cada avião, conte o número de voos antes do primeiro atraso de mais de 1 hora.
Editor de Scripts
O editor de scripts é um ótimo lugar para colocar o seu código. Continue testando e experimentando
utilizando o console, mas uma vez que você tenha escrito código que funciona e faz o que você quer,
coloque-o no editor de script. O RStudio salvará automaticamente o conteúdo do editor quando você sair
e o carregará automaticamente quando o reabrir. No entanto, é sempre uma boa ideia salvar seus scripts
regularmente e fazer backups.
Executando Código
O editor de scripts é um ótimo lugar para construir gráficos complexos com ggplot2 ou longas sequências
de instruções dplyr. Para utilizar bem o editor de script é conveniente memorizar um dos atalhos de
teclado mais importantes: [Ctrl + Enter]. Ele executa a atual expressão R do editor de scripts no console.
Por exemplo, veja o código abaixo. Se o cursor estiver posicionado em █ na figura a seguir, pressionar o
[Ctrl + Enter] executará o comando completo que gera 'not_cancelled'. Ele também mudará o cursor para
a próxima declaração (começando com 'not_cancelled %>%'). Isso facilita a execução do seu script
completo posicionando o cursor ao final da instrução a ser executada e pressionando repetidamente o
[Ctrl + Enter].
library(dplyr)
library(nycflights13)
not_cancelled <- flights %>%
filter(!is.na(dep_delay)█, !is.na(arr_delay))
not_cancelled %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay))
Em vez de executar instrução por instrução, você também pode executar o script completo em uma única
etapa teclando [Ctrl + Shift + S]. Fazer isso regularmente é uma ótima maneira de verificar se você incluiu
todas as partes importantes do seu código no script.
Você sempre deve começar o seu script com os pacotes que utilizará. Dessa forma, se você compartilhar
seu código com outras pessoas, elas podem facilmente saber quais pacotes são utilizados e precisam estar
instalados. Observe, no entanto, que você não deve incluir 'install.packages()' ou 'setwd()' em um script
que você compartilha, pois isso poderá alterar as configurações do computador da outra pessoa.
Daqui para frente você deve trabalhar através do editor de scripts. Com o tempo, trabalhar com ele e
enviar código para o console se tornará tão natural que você nem vai perceber.
Note que no topo do editor de scripts o RStudio apresenta uma conveniente barra de botões. Passe o
mouse sobre cada um deles e procure descobrir a função e utilidade de cada um e passe a utilizá-los.
O editor de script também destacará erros de sintaxe que existirem no seu código com uma linha
vermelha e um X na barra lateral. Passe o mouse sobre eles para consultar a dica do RStudio que o ajudará
a corrigir o erro.
Você também pode obter o diretório de trabalho atual executando a instrução a seguir no console:
getwd()
[1] "C:/GIT/DATALAB/R"
Como usuário novato de R não há nenhum problema em deixar que seu diretório de trabalho inicial seja
um diretório de documentos de usuário do Windows ou qualquer outro diretório em seu computador.
Também não há problema em utilizar a configuração padrão do RStudio que automaticamente preserva
sua área de trabalho (workspace padrão) entre várias sessões de utilização.
Porém, para começar a utilizar o R seriamente como profissional você precisará evoluir e passar a
administrar seus projetos de análise dedados e respectivos diretórios e espaços de trabalho.
Projeto RStudio
Para começar a trabalhar com projetos a primeira providência a tomar é instruir o RStudio a não preservar
sua área de trabalho entre sessões.
Para isso você deve escolher a opção “Global Options” do menu “Tools” de forma que seja apresentada a
janela ilustrada na figura anterior. Através desta janela você pode configurar todos os elementos do
RStudio, sendo que há centenas de opções, mas que estão além do nosso escopo. Porém entre elas está
a sua área de trabalho ou Workspace, conforme indicado na próxima figura.
Desmarque a caixa “Restore .RData into workspace at startup” e altere a opção “Save workspace to
.RData on exit” para “Never” (nunca).
Isso vai causar-lhe alguma dificuldade no curto prazo, porque agora quando você reiniciar RStudio ele não
vai lembrar os resultados do código que você executou da última vez. Mas essa dor de curto prazo vai
passar e salvá-lo da agonia a longo prazo porque forçará você a gravar todas as interações importantes
em seu código. Não há nada pior do que descobrir algum tempo depois que você só guardou os resultados
de um cálculo importante em seu espaço de trabalho, não o código do script do cálculo em si.
Há ótimos de atalhos de teclado que trabalharão juntos para garantir que você tenha capturado as partes
importantes do seu código no editor de scripts, entre eles:
• [Ctrl + Shift + F10] para reiniciar o RStudio.
• [Ctrl + Shift + S] para voltar ao script atual.
• [Ctrl + L] para limpar a janela Console.
Os profissionais em R (como você) sempre preservam todos os arquivos associados a um projeto de
análise de dados --- dados de entrada, scripts R, resultados analíticos, números etc. Esta é uma prática tão
sábia e necessária que o RStudio tem suporte integrado para isso através do conceito de Projetos.
Vamos criar um primeiro projeto para você utilizar enquanto você estiver trabalhando neste curso. Clique
em File > New Project, então o RStudio apresentará as janelas ilustradas a seguir:
Na primeira janela você deve selecionar “New Directory”, na segunda janela “New Project”, na terceira
especificar o nome do seu diretório de trabalho em “Directory name” e a pasta onde ficará localizado no
seu computador em “Create project as subdirectory of:”, conforme ilustra a quarta janela, mas defina o
seu nome e uma pasta do seu computador, pois as que aparecem nesta figura são as do meu computador.
Não defina qualquer nome e qualquer pasta para não se arrepender no futuro; sempre procure definir
um nome adequado para o seu projeto e um local adequado para armazená-lo pois precisará dele no
futuro. Finalmente clique o botão “Create Project”.
Parabéns! O RStudio deve ter criado um projeto novinho para você trabalhar. Note na janela Files o nome
do seu projeto e na janela Console a pasta onde estará sendo gravado, conforme ilustram as figuras
apresentadas a seguir.
Agora digite os seguintes comandos no editor de script, e salve o arquivo, chamando-o de "diamantes.R".
Em seguida, execute o script completo que salvará um arquivo PDF e outro CSV em seu diretório de
projeto. Por enquanto não se preocupe com os detalhes, você vai aprendê-los oportunamente.
install.packages("hexbin")
library(tidyverse)
ggplot(diamonds, aes(carat, price)) + geom_hex()
ggsave("diamonds.pdf")
write_csv(diamonds, "diamonds.csv")
Saia do RStudio. Utilizando o Windows Explorer inspecione a pasta associada ao seu projeto e observe o
arquivo com extensão .Rproj. Clique duas vezes nesse arquivo para reabrir o projeto. Observe que você
volta para onde parou: é o mesmo diretório de trabalho e histórico de comando, e todos os arquivos em
que você estava trabalhando ainda estão abertos. Não é ótimo!!
Localize o arquivo 'diamonds.pdf' na janela Files (acima) e dê um clique nele. Um dia você vai querer
refazer um gráfico ou apenas entender de onde ele veio. Se você salvar rigorosamente gráficos em
arquivos utilizando instruções em R, como fizemos nesse primeiro projeto, e nunca com o mouse e a área
de transferência, você será capaz de reproduzir trabalhos de análise anteriores com facilidade.
Clique agora sobre o arquivo diamantes.csv e escolha a opção “Import Dataset” para verificar os dados
que geraram o gráfico. Cancele ou salve o dataset em seguida. Bacana não!!
Resumindo, os projetos do RStudio permitem que você crie um fluxo de trabalho profissional que o
atenderão bem no futuro quando estiver trabalhando em seus próprios projetos de análise de dados.
1. Crie um projeto RStudio para cada projeto de análise de dados que desenvolver.
2. Mantenha os arquivos dos dados fonte lá; vamos falar sobre carregá-los em R em Importação de
dados.
3. Mantenha os todos os seus scripts lá; edite-os e execute-os em partes ou como um todo, conforme
for conveniente.
4. Salve seus resultados importantes, como gráficos e dados tratados ou transformados.
5. Por questões de portabilidade entre máquinas, procure utilizar caminhos relativos, não caminhos
absolutos. No caso do nosso exemplo, em vez de especificar o diretório de trabalho como
“C:/GIT/DATALAB/PECE”, especificando apenas “~/PECE” a caminho anterior será relativo ao diretório
atual.
6. Tudo o que você precisa estará em um lugar, e separado de todos os outros projetos em que você
estiver trabalhando.
dados é apenas uma aplicação do EDA: você faz perguntas sobre se seus dados atendem ou não às suas
expectativas. Para fazer a limpeza de dados, você precisará implantar todas as ferramentas do EDA:
visualização, transformação e modelagem.
Seu objetivo durante o EDA é desenvolver uma compreensão de seus dados. A maneira mais fácil de fazer
isso é usar perguntas como ferramentas para orientar sua investigação. Quando você faz uma pergunta,
a pergunta foca sua atenção em uma parte específica do seu conjunto de dados e ajuda você a decidir
quais gráficos, modelos ou transformações fazer.
Não há nenhuma regra sobre quais perguntas você deve fazer para orientar sua pesquisa. No entanto,
dois tipos de perguntas sempre serão úteis para fazer descobertas dentro de seus dados. Você pode
formular perguntas como:
1. Que tipo de variação ocorre dentro das minhas variáveis?
2. Que tipo de covariação ocorre entre minhas variáveis?
Para responder estas perguntas você precisa ter em mente os seguintes conceitos fundamentais:
• Uma variável é uma quantidade, qualidade ou propriedade que você pode medir sobre algo ou
algum objeto.
• Um valor é um dado que representa estado de uma variável quando você a mede. O valor de
uma variável pode mudar de medição para medição.
• Uma observação é um conjunto de valores de medidas feitas sobre algo ou um objeto em
condições semelhantes (você geralmente faz todas as medidas em uma observação ao mesmo
tempo). Uma observação conterá vários valores, cada um associado a uma variável diferente.
Uma observação pode ser entendida como um objeto de dados.
• Dados tabulares é um conjunto de valores, cada um associado a uma variável e a uma
observação. Os dados tabulares são _tidy_ (estruturados) se cada valor for colocado em sua
própria "célula", cada variável em sua própria coluna e cada observação em sua própria linha.
Nos próximos tópicos utilizaremos, como exemplo, o conjunto de dados diamonds que, que faz parte da
biblioteca tidyverse e descreve aproximadamente 50 mil diamantes. Você pode visualizá-lo executando
o comando abaixo. Os nomes das colunas indicam as características de cada diamante, sendo carat
(quilate), price (preço em US$), x (altura), y (largura) e z (profundidade) em milímetros.
library(tidyverse)
view(diamonds)
Visualizando Variáveis
Como você visualiza a distribuição dos valores de uma variável dependerá se a variável é categórica ou
contínua. Uma variável é categórica se ela só pode assumir um de um pequeno conjunto de valores. Em
R, variáveis categóricas geralmente são salvas como fatores ou vetores de caracteres. Para examinar a
distribuição de uma variável categórica, use um gráfico de barras:
ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut))
A altura das barras mostra quantas observações ocorreram a cada valor x. Você pode calcular esses
valores manualmente com 'dplyr::count()':
diamonds %>%
count(cut)
Uma variável é contínua se pode assumir qualquer valor de um conjunto infinito de valores ordenados.
Números e horários são dois exemplos de variáveis contínuas. Para examinar a distribuição de uma
variável contínua, use um histograma:
ggplot(data = diamonds) +
geom_histogram(mapping = aes(x = carat), binwidth = 0.5)
Um histograma divide o eixo x em faixas (bins) igualmente espaçadas e, em seguida, usa a altura de uma
barra para exibir o número de observações que caem em cada faixa. No gráfico acima, a barra mais alta
mostra que quase 30.000 observações têm um valor de 'quilate' entre 0,25 e 0,75, que são as bordas
esquerda e direita da barra.
Você pode definir a largura dos intervalos em um histograma com o argumento 'binwidth', que é medido
nas unidades da variável 'x'. Você deve sempre explorar uma variedade de binwidths ao trabalhar com
histogramas, pois diferentes larguras de binwid podem revelar padrões diferentes. Por exemplo, aqui está
como o gráfico acima parece quando ampliamos apenas os diamantes com um tamanho de menos de três
quilates e escolhemos uma largura de binwid menor.
smaller <- diamonds %>%
filter(carat < 3)
Se você desejar sobrepor vários histogramas no mesmo gráfico, utilize 'geom_freqpoly()' em vez de
'geom_histogram()'. 'geom_freqpoly()' realiza o mesmo cálculo de 'geom_histogram()', mas em vez de
exibir as contagens com barras, usa linhas. É mais fácil entender linhas sobrepostas do que barras.
ggplot(data = smaller, mapping = aes(x = carat, colour = cut)) +
geom_freqpoly(binwidth = 0.1)
Valores Típicos
Tanto em gráficos de barras quanto em histogramas, barras altas mostram os valores comuns de uma
variável, e barras mais curtas mostram valores menos comuns. Lugares que não possuem barras revelam
valores que não foram vistos em seus dados. Para transformar essas informações em perguntas úteis,
procure algo inesperado:
Grupos de valores semelhantes sugerem que existem subgrupos em seus dados. Para entender os
subgrupos, pergunte:
• Como as observações dentro de cada aglomerado são semelhantes umas às outras?
• Como as observações em grupos separados são diferentes umas das outras?
• Como você pode explicar ou descrever os aglomerados?
• Por que a aparência dos aglomerados pode ser enganosa?
O histograma abaixo mostra o comprimento (em minutos) de 272 erupções do gêiser Old Faithful no
Parque Nacional de Yellowstone. Os tempos de erupção parecem estar agrupados em dois grupos: há
erupções curtas (de cerca de 2 minutos) e erupções longas (4-5 minutos), mas pouco no meio.
ggplot(data = faithful, mapping = aes(x = eruptions)) +
geom_histogram(binwidth = 0.25)
Muitas das perguntas acima levarão você a explorar uma relação entre variáveis por exemplo, para ver se
os valores de uma variável podem explicar o comportamento de outra variável.
Valores Incomuns
Outliers são observações que são incomuns; pontos de dados que não parecem se encaixar no padrão. Às
vezes, os outliers são erros de entrada de dados; outras vezes outliers sugerem ciência nova importante.
Quando você tem um monte de dados, outliers às vezes são difíceis de ver em um histograma. Por
exemplo, pegue a distribuição da variável 'y' do conjunto de dados de diamantes. A única evidência de
outliers são os limites extraordinariamente amplos no eixo x.
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5)
Há tantas observações nas faixas comuns que as faixas raras são tão pequenas que você não pode vê-las
(embora talvez se você olhar atentamente para 0 você vai detectar algo). Para facilitar a visão dos valores
incomuns, precisamos ampliar os pequenos valores do eixo y com 'coord_cartesian()':
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5) +
coord_cartesian(ylim = c(0, 50))
('coord_cartesian()' também tem um argumento 'xlim()' para quando você precisa ampliar o eixo x.
ggplot2 também tem funções 'xlim()' e 'ylim()' que funcionam ligeiramente diferente: eles jogam fora os
dados fora dos limites.)
Isso nos permite ver que existem três valores incomuns: 0, ~30 e ~60. Nós os eliminamos com dplyr:
unusual <- diamonds %>%
filter(y < 3 | y > 20) %>%
select(price, x, y, z) %>%
arrange(y)
unusual
A variável 'y' mede uma das três dimensões desses diamantes, em mm. Sabemos que os diamantes não
podem ter uma largura de 0mm, então esses valores devem estar incorretos. Também podemos suspeitar
que medições de 32mm e 59mm são implausíveis: esses diamantes têm mais de uma polegada de
comprimento, mas não custam centenas de milhares de dólares!
É uma boa prática repetir sua análise com e sem os outliers. Se eles têm um efeito mínimo sobre os
resultados, e você não pode descobrir por que eles estão lá, é razoável substituí-los por valores faltantes,
e seguir em frente. No entanto, se eles têm um efeito substancial em seus resultados, você não deve
deixá-los retirá-los sem justificativa. Você precisará descobrir o que os causou (por exemplo, um erro de
entrada de dados) e divulgar que você os removeu em sua gravação.
Exercícios
1. Explore a distribuição de cada uma das variáveis 'x', 'y' e 'z' em 'diamantes'. O que você pode aprender?
Pense em um diamante e como você pode decidir qual dimensão é o comprimento, largura e
profundidade.
2. Explore a distribuição de 'preço'. Você descobriu algo incomum ou surpreendente? (Dica: Pense
cuidadosamente na largura da faixa (binwidth) e certifique-se de experimentar uma ampla gama de
valores.)
3. Quantos diamantes são 0,99 quilates? Quantos são 1 quilate? Qual você acha que é a causa da
diferença?
4. Compare e contraste 'coord_cartesian()' vs 'xlim()' ou 'ylim()' ao dar zoom em um histograma. O que
acontece se você deixar "binwidth" sem set?
Valores Faltantes
Se você encontrou valores incomuns em seu conjunto de dados e precisa continuar a sua análise, você
tem duas opções.
1. Eliminar toda a linha com os valores estranhos, por exemplo, com valores em y muito pequenos ou
muito grandes:
diamonds2 <- diamonds %>%
filter(between(y, 3, 20))
Esta alternativa talvez seja um pouco radical e, portanto, não recomendável. Só porque uma medida
parece inválida, não significa que todas as demais medidas serão. Além disso, se você tiver dados de
baixa qualidade, ao aplicar este critério a todas as variáveis, poderão sobrar poucos dados para
analisar.
2. Substituir os valores incomuns ou estranhos por valores faltantes. A maneira mais fácil de fazer isso é
usar 'mutate()' para substituir uma variável por uma cópia modificada. Você pode usar a função
'ifelse()' para substituir valores incomuns por 'NA':
'ifelse()' tem três argumentos. O primeiro "o teste" de argumento deve ser um vetor lógico. O resultado
conterá o valor do segundo argumento, 'sim', quando 'o teste' for 'TRUE', e o valor do terceiro argumento,
'não', quando for 'FALSE'. Alternativamente a ifelse, você pode usar 'dplyr::case_when()'. 'case_when()' é
particularmente útil dentro do mutate quando você quer criar uma nova variável que se baseia em uma
combinação complexa de variáveis existentes.
Para suprimir o aviso da existência de valores faltantes NA, defina 'na.rm = TRUE':
Covariação
A variação descreve o comportamento dos valores de medida dentro de uma mesma variável. A
covariação, por outro lado, descreve este comportamento entre variáveis. A covariação é a tendência de
que os valores de duas ou mais variáveis variem juntos de forma relacionada. A melhor maneira de
detectar a covariação é visualizar a relação entre duas ou mais variáveis. Como você faz isso depende
novamente do tipo de variáveis envolvidas.
É quase impossível ver a diferença na distribuição porque as contagens gerais diferem muito:
ggplot(diamonds) +
geom_bar(mapping = aes(x = cut))
Para facilitar a comparação, precisamos trocar o que é exibido no eixo y. Em vez de exibir a contagem,
vamos exibir __density__, que é a contagem padronizada de modo que a área sob cada polígono de
frequência é um.
ggplot(data = diamonds, mapping = aes(x = price, y = ..density..)) +
geom_freqpoly(mapping = aes(colour = cut), binwidth = 500)
Há algo bastante surpreendente sobre este gráfico - parece que diamantes fair (a menor qualidade) têm
o preço médio mais alto! Mas talvez seja porque polígonos de frequência sejam difíceis de interpretar.
Portanto, precisamos de uma alternativa para tentar melhorar este entendimento.
Uma boa alternativa para exibir a distribuição de uma variável contínua dividida por uma variável
categórica é o gráfico boxplot. Conforme ilustrado na figura a seguir, cada boxplot consiste em:
• Uma caixa que se estende do percentil 25 da distribuição até o percentil 75, uma distância
conhecida como faixa interquartil (IQR). No meio da caixa está uma linha que exibe a mediana,
ou seja, 50º percentil, da distribuição. Estas três linhas fornecem uma noção da propagação da
distribuição e se a distribuição é ou não simétrica sobre a mediana ou inclinada para um lado.
• Pontos visuais que exibem observações que caem mais de 1,5 vezes o IQR de cada borda da caixa.
Esses pontos de saída são incomuns, por isso são plotados individualmente.
• Uma linha (ou bigode de gato) que se estende de cada extremidade da caixa e vai para o ponto
mais distante não-outlier na distribuição.
Vamos então dar uma olhada na distribuição do preço dos diamantes por corte usando 'geom_boxplot()':
Vemos muito menos informações sobre a distribuição, portanto, boxplots são muito mais compactos para
que possamos compará-los mais facilmente. Eles suportam a contraintuitiva constatação de que
diamantes de melhor qualidade são mais baratos em média. Como você explicaria isso?
O corte ('cut') é um fator ordenado: fair é pior do que good, o que é pior do que very good e assim por
diante. Muitas variáveis categóricas não têm uma ordem tão intrínseca, como neste caso, então você
pode querer reordená-las para gerar uma exibição mais informativa. Uma maneira de fazer isso é utilizar
a função 'reorder()'.
Por exemplo, pegue a variável 'classe' no conjunto de dados 'mpg' que já utilizamos. Você pode estar
interessado em saber como a milhagem da rodovia varia entre as classes de veículos, que neste caso não
são ordenadas. Para tornar a tendência mais fácil de ver, podemos ordenar a 'classe' com base no valor
médio de 'hwy' (potência):
ggplot(data = mpg) +
geom_boxplot(mapping = aes(x = reorder(class, hwy, FUN = median), y
= hwy))
Se você tiver nomes de variáveis longas, 'geom_boxplot()' funcionará melhor se você fizer uma rotação
de 90°. Você pode fazer isso com 'coord_flip()'.
ggplot(data = mpg) +
geom_boxplot(mapping = aes(x = reorder(class, hwy, FUN = median), y
= hwy)) +
coord_flip()
O tamanho de cada círculo no gráfico mostra quantas observações ocorreram em cada combinação de
valores. A covariação aparecerá como uma forte correlação entre valores x e y específicos.
As dispersões tornam-se menos úteis à medida que o tamanho do seu conjunto de dados cresce, porque
os pontos começam a se sobrepor, e se acumulam em áreas de preto uniforme (como acima).
Outra opção é criar faixas (bins) para uma variável contínua para que ela aja como uma variável categórica.
Então você pode usar uma das técnicas para visualizar a combinação de uma variável categórica e uma
variável contínua. Por exemplo, você pode criar faixas (bins) para 'quilate' e, em seguida, para cada grupo,
exibir um boxplot:
ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_width(carat, 0.5)))
A função cut_width(x, largura), como usado acima, divide 'x' em faixas de acordo com a largura
especificada. Por padrão, as plataformas de caixa parecem aproximadamente as mesmas (além do
número de outliers) independentemente de quantas observações existem, por isso é difícil dizer que cada
boxplot resume um número diferente de pontos. Uma maneira de mostrar isso é tornar a largura do
boxplot proporcional ao número de pontos com 'varwidth = TRUE'.
Outra abordagem é exibir aproximadamente o mesmo número de pontos em cada faixa. Esse é o trabalho
de "cut_number()":
ggplot(data = diamonds, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_number(carat, 20)))
Padrões e modelos
Padrões em seus dados fornecem pistas sobre relacionamentos. Se existir uma relação sistemática entre
duas variáveis, ela aparecerá como um padrão nos dados. Se você detectar um padrão, pergunte:
• Esse padrão pode ser devido a coincidência (ou seja, acaso)?
• Como você pode descrever a relação revelada pelo padrão?
• Quão forte é a relação revelada pelo padrão?
• Que outras variáveis podem afetar a relação?
• A relação muda se você olhar para subgrupos individuais dos dados?
Os padrões fornecem uma das ferramentas mais úteis para cientistas de dados porque revelam a
covariação. Se você pensa na variação como um fenômeno que cria incerteza, a covariação é um
fenômeno que a reduz. Se duas variáveis covariam, você pode usar os valores de uma variável para fazer
melhores previsões sobre os valores da outra. Se a covariação for devido a uma relação causal (um caso
especial), então você pode usar o valor de uma variável para controlar o valor da outra.
Os modelos são uma ferramenta para extrair padrões de dados. Por exemplo, considere os dados dos
diamantes. É difícil entender a relação entre corte e preço, porque corte e quilate, e quilate e preço estão
fortemente relacionados. É possível usar um modelo para remover a relação muito forte entre preço e
quilate para que possamos explorar as sutilezas que permanecem. O código a seguir se encaixa em um
modelo que prevê 'preço' de 'quilate' e, em seguida, calcula os resíduos (a diferença entre o valor previsto
e o valor real). Os resíduos nos dão uma visão do preço do diamante, uma vez que o efeito do quilate foi
removido.
library(modelr)
mod <- lm(log(price) ~ log(carat), data = diamonds)
ggplot(data = diamonds2) +
geom_point(mapping = aes(x = carat, y = resid))
Uma vez que você removeu a forte relação entre quilate e preço, você pode ver o que você espera na
relação entre corte e preço: em relação ao seu tamanho, diamantes de melhor qualidade são mais caros.
ggplot(data = diamonds2) +
geom_boxplot(mapping = aes(x = cut, y = resid))
Se você quiser saber mais sobre o ggplot2 há vários livros disponíveis, inclusive alguns com acesso via
Web, como os relacionados na bibliografia desta apostila.
A maioria das funções do readr está focada em transformar arquivos texto planos em data frames
tabulares:
• 'read_csv()' lê arquivos delimitados por vírgula;
• 'read_csv2()' lê arquivos delimitados por ponto e vírgula (nosso caso, a vírgula é usada no lugar
do ponto decimal). O MS Excel, versão em português, por padrão lê e grava arquivos csv
delimitados por ponto e vírgula;
• 'read_tsv()' lê arquivos delimitados por tabulações;
• 'read_delim()' lê em arquivos com qualquer delimitador.
• 'read_fwf()' lê arquivos de largura fixa. Você pode especificar campos por suas larguras com
'fwf_widths()' ou sua posição com 'fwf_positions()'.
• `read_table()` lê uma variação comum de arquivos de largura fixa onde as colunas são separadas
pelo espaço branco.
Todas essas funções têm sintaxe semelhante: uma vez que você tenha dominado uma, você pode usar as
outras com facilidade. Vamos focar em 'read_csv()'. Não só os arquivos csv são uma das formas mais
comuns de armazenamento de dados, mas uma vez que você entende 'read_csv()', você pode facilmente
aplicar seu conhecimento a todas as outras funções do readr.
Quando você executa 'read_csv()' ele imprime uma especificação de coluna que dá o nome e o tipo de
cada coluna. Essa é uma parte importante do readr.
Você também pode fornecer um arquivo csv inline. Isso é útil para experimentar o readr e para criar
exemplos reprodutíveis para compartilhar com outros:
read_csv("a,b,c
1,2,3
4,5,6")
Em ambos os casos 'read_csv()' usa a primeira linha dos dados para os nomes das colunas, o que é uma
convenção muito comum. Há dois casos em que você pode querer ajustar este comportamento.
Às vezes há algumas linhas de metadados no topo do arquivo. Você pode usar 'skip = n' para pular as
primeiras linhas 'n'; ou usar 'comment = #'' para eliminar todas as linhas que começam com (por exemplo)
'#'.
Os dados podem não ter nomes de colunas. Você pode usar 'col_names = FALSE' para dizer ao 'read_csv()'
para não tratar a primeira linha como títulos e, em vez disso, rotulá-los sequencialmente de 'X1' para 'Xn':
read_csv("1,2,3\n4,5,6", col_names = FALSE)
Outra opção que normalmente precisa de ajustes é 'na': isso especifica o valor (ou valores) que são usados
para representar valores ausentes em seu arquivo:
read_csv("a,b,c\n1,2,?", na = "?")
Isso é tudo que você precisa saber para ler ~75% dos arquivos CSV que encontrará na prática. Você
também pode adaptar facilmente isso que aprendeu para ler arquivos separados por tabulação com
'read_tsv()' e de largura fixa com 'read_fwf()'. Para ler em arquivos mais sofisticados, você precisará
aprender mais sobre como o readr analisa cada coluna, transformando-os em vetores R.
Nestas instruções o banco exemplificado é o MS SQL Server, como você pode notar pelo parâmetro
Driver={SQL Server}.
install.packages("RODBC")
library(DBI)
con <- dbConnect(odbc::odbc(), .connection_string = "Driver={SQL
Server};Server=<nome_servidor>;Database=<nome_banco>;User=<nome_usuari
o>;Password=<senha_acesso>", timeout = 10)
Após a conexão o RStudio apresentará na janela Connections todas as informações do banco de dados,
permitindo inclusive a visualização direta dos dados de cada tabela, conforme ilustra a figura anterior.
Para executar uma consulta em uma tabela do banco de dados conectado e criar um data frame no R com
o resultado da consulta você pode executar as seguintes instruções:
#Conexão com o banco de dados
install.packages(“RODBC”)
library(DBI)
con <- dbConnect(odbc::odbc(), .connection_string = "Driver={SQL
Server};Server=localhost;Database=EXEMPLO;User=eumesmo;Password=senhas
ecreta", timeout = 10)
teste <- dbGetQuery(con, 'SELECT * FROM PESSOA')
view(teste)
A biblioteca DBI define uma interface de comunicação entre sistemas de gerenciamento de banco de
dados SQL e o R. Todas as classes deste pacote são virtuais e precisam ser estendidas pelas várias
implementações de R/DBMS (os chamados backends DBI). A biblioteca DBI (DataBase Interface)
implementa as seguintes funções básicas:
• dbConnect(): conecta-se a um DBMS que passa pelo procedimento de autenticação adequado.
• dbGetQuery(): retorna o resultado de uma consulta como um data frame R.
• dbReadTable(): lê uma tabela de banco de dados para um data frame R, opcionalmente
convertendo uma coluna em nomes de linha e convertendo os nomes das colunas em
identificadores R válidos.
• dbWriteTable(): escreve, sobrescreve ou adiciona um data frame R a uma tabela de banco de
dados, convertendo nomes de linha opcionalmente em uma coluna e especificando tipos de
dados SQL para campos.
• dbDisconnect(): fecha a conexão, descarta todo o trabalho pendente e libera recursos (por
exemplo, memória, soquetes).
Fatores
Introdução
Em R, fatores são utilizados para trabalhar com variáveis categóricas, variáveis que possuem um conjunto
fixo e conhecido de valores possíveis. Eles também são úteis quando você deseja exibir vetores de
caracteres em uma ordem não alfabética.
Historicamente, fatores eram muito mais fáceis de trabalhar do que caracteres. Como resultado, muitas
das funções na base R convertem automaticamente caracteres em fatores.
Para trabalhar com fatores, usaremos o pacote forcats, que faz parte do core tidyverse. Ele fornece
ferramentas para lidar com variáveis categóricas usando uma ampla gama de funções auxiliares para
trabalhar com fatores.
library(tidyverse)
library(forcats)
Criando Fatores
Imagine que você tem uma variável que registra mêses:
x1 <- c("Dec", "Abr", "Jan", "Mar")
Usar uma string para gravar essa variável tem dois problemas:
Há apenas doze meses possíveis, e não há nada que o proteja de erros de digitação:
x2 <- c("Dez", "Abr", "Jam", "Mar")
Você pode corrigir estes problemas com um fator. Para criar um fator, você deve começar criando uma
lista de levels válida:
month_levels <- c(
"Jan", "Fev", "Mar", "Abr", "Mai", "Jun",
"Jul", "Ago", "Set", "Out", "Nov", "Dez"
)
E quaisquer valores que não estejam no conjunto serão silenciosamente convertidos em NA:
y2 <- factor(x2, levels = month_levels)
y2
Se você omitir os níveis, eles serão retirados dos dados em ordem alfabética:
factor(x1)
Às vezes você prefere que a ordem dos níveis corresponda à ordem da primeira aparição nos dados. É
possível fazer isso ao criar o fator definindo níveis para 'unique(x)' ou após o fato, com 'fct_inorder()':
f1 <- factor(x1, levels = unique(x1))
f1
Se você precisar acessar o conjunto de níveis válidos diretamente, você pode fazê-lo com 'levels()':
levels(f2)
Referências
Bibliografia
• R para Data Science, Wickham, H & Grolemund, G, Alta Books, 2019, acessível em
https://r4ds.had.co.nz/index.html
• Livro sobre o ggplot2 acessível em https://ggplot2-book.org/
• Ggplot2 – Elegant Graphics for Data Analysis, Second Edition, Wickham, Hadley, Springer, 2016
, acessível em http://www.ievbras.ru/ecostat/Kiril/R/Biblio_N/R_Eng/Wickham2016.pdf
• RStudio Documentation, disponível em https://docs.rstudio.com/
• R Manuals, disponíveis em https://cran.r-project.org/manuals.html
Vídeos
• R Programming Tutorial – Learn the Basics of Statistical Computing, acessível em
https://www.youtube.com/watch?v=_V8eKsto3Ug
• R for Data Science, acessível em https://www.youtube.com/watch?v=NVyOEwOJgNQ
• R vs. Python – What should I learn in 2020, https://www.youtube.com/watch?v=eRP_J2yLjSU