Esta apostila visa ensinar o básico de programação de maneira simples e com exemplos de aplicação real nas nossas atividades enquanto funcionários do CCS. O curso visa ensinar quem nunca teve contato com programação e, por isso, parte do básico. O objetivo é promover a capacitação, a cultura de dados e uma maior produtividade nas nossas atividades.
Por quê programar?
Para entender o poder e a utilidade da programação, mesmo para tarefas cotidianas, precisamos entender o básico de como um código ou script de programação funciona.
Um script nada mais é do que uma “receita de bolo” de como o computador vai realizar uma série de tarefas. Mas nós humanos, quando seguimos uma receita de bolo, às vezes colocamos uma xícara de açúcar mais generosa ou então ficamos na dúvida se os 3 ovos que temos são tão grandes quanto os 3 ovos que a Rita Lobo usou.
Já um computador não sofre com essas questões. As instruções são seguidas à risca, ou seja, códigos de computador geram resultados reprodutíveis. Para entender isso, vamos a um exemplo prático.
Exemplo 1:
Como faríamos para instruir um colega a reproduzir o gráfico a seguir a partir da base fornecida?
Figura 1: Gráfico de Faturamento por Bandeira 2024
Como podemos ver, instruir uma pessoa a realizar uma sequência de atividades pode ser complicado e o resultado não necessariamente será como esperamos. Mas quando estamos instruindo um computador, geralmente é fácil obter resultados reprodutíveis. Vejamos a seguir:
Code
# Este é o visual que um código em R tem# Linhas iniciadas por cerquilha(#) são comentários, ou seja, são linhas que# servem apenas para o operador humano que está lendo o código e não têm nenhuma# influência no fluxo do script e nem realizam nenhuma operação ou tarefa# Geralmente utilizamos linhas de comentários para explicar nosso raciocínio# e o que estamos fazendo a alguém que eventualmente vá ler nosso código# A função (explicaremos com mais detalhes o que é uma função posteriormente)# library carrega pacotes (também explicaremos o que são pacotes)# No caso a seguir, estamos carregando diversos pacoteslibrary(ggplot2)library(stringr)library(dplyr)library(lubridate)library(RColorBrewer)library(unikn)library(scales)# Define as paletas de corespaleta_sicoob <-c("#003641","#00AE9D","#49479D", "#7DB61C","#C9D200")# Gera uma paleta com 10 cores a partir da paleta originalpaleta_sicoob_expandida <- grDevices::colorRampPalette(paleta_sicoob)(10)# Gera uma paleta com 6 cores a partir da paleta originalpaleta_sicoob_6 <- grDevices::colorRampPalette(paleta_sicoob)(6)# Aqui guardamos na variável (vai ser explicado) chamada caminho_arquivo # o caminho para o arquivo que será lidocaminho_arquivo <-"C:\\Users\\paulo.rego\\OneDrive - Sicoob\\CursoProgEx1.csv"# A função read.csv2 lê arquivos no formato csv# Aqui guardamos na variável dados_faturamento os valores lidos do arquivodados_faturamento <-read.csv2(caminho_arquivo)names(dados_faturamento) <-c("Faturamento", "Bandeira", "Data")dados_faturamento$Bandeira <-stringr::str_to_title(dados_faturamento$Bandeira)dados_faturamento$Data <- lubridate::dmy_hm(dados_faturamento$Data)grafico1 <-ggplot(dados_faturamento,aes(x = Data,y = Faturamento,fill = Bandeira)) +geom_area() +labs(title ="Faturamento por Bandeira (2024)",y ="R$ Bilhões",x =NULL,fill =NULL )+scale_fill_manual(values = paleta_sicoob_6) +theme(plot.background =element_rect(fill ="#003641", color =NA),panel.background =element_rect(fill ="#003641", color =NA),text =element_text(color ="white"),axis.text =element_text(color ="white"),axis.title =element_text(color ="white"),plot.title =element_text(size =16, face ="bold", hjust =0.5),legend.box.background =element_rect(fill ="transparent", color ="transparent"),legend.background =element_rect(fill ="transparent", color ="transparent"),legend.key =element_rect(fill ="transparent", color ="transparent") ) +scale_y_continuous(labels =label_number(scale =1e-9))grafico1
Conhecendo o R
O R é uma linguagem de programação que foi criada em 1993, inspirada na linguagem S (que foi desenvolvida nos Bell Labs nos anos 70). R foi criada com o foco na sua utilização em análise estatística e análise de dados. Hoje em dia é uma linguagem relativamente popular na área de análise de dados e é utilizada principalmente nos ramos de finanças, estatística e bioinformática.
Vantagens do R
É uma linguagem versátil que conta com uma extensa biblioteca de pacotes de funções. Tem foco em estatística e análise e manipulação de dados e essas são as maiores aplicações dos nossos scripts por aqui.
R é uma linguagem feita pensando em cálculos vetorizados desde a sua concepção. Nos próximos tópicos isso ficará mais claro mas por enquanto basta saber que isso gera uma grande eficiência em cálculos complexos.
Desvantagens
Em comparação a Python, pode haver menos material para consulta na internet.
R tem um consumo muito intensivo de memória ram, o que pode tornar a leitura de grandes bases mais complicada em sistemas com hardware menos robusto
R conta com menos suporte para criação de aplicações gerais como aplicações web ou APIs. Para essas tarefas seria mais adequado escolher outras linguagens como Rust, Python, C++ etc. Mas como esse de habilidade está fora do nosso escopo de trabalho, não temos porque nos preocupar.
Conhecendo o RStudio
O RStudio é uma IDE ou Ambiente de Desenvolvimento Integrado (em inglês, Integrated Development Environment). Uma IDE é um software que junta várias ferramentas de desenvolvimento para nossa facilidade. É plenamente possível desenvolver scripts e programas sem utilizar uma IDE, fazendo tudo no console ou em editores de texto mas as IDEs facilitam a nossa vida. A IDE escolhida para o curso e para a utilização do R em geral é o RStudio. O RStudio é a IDE mais completa e mais popular para utilização do R.
Conhecendo os Painéis do RStudio
Em sua configuração padrão o RStudio está organizado em 4 painéis. Ao longo do curso vamos utilizar a organização padrão do RStudio que veio na sua instalação.
Painel do Editor
Esse painel se encontra no lado superior esquerdo da nossa tela por padrão. É um editor de texto onde vamos escrever nossos códigos. Esse painel é onde passamos a maior parte do nosso tempo enquanto estamos utilizando o RStudio. O Editor conta com algumas funções para tornar nossa vida mais fácil como a de autocompletar código e de colorir a sintaxe para uma melhor compreensão do código.
Painel do ambiente
Esse painel fica no lado superior direito por padrão. Nele encontramos algumas abas como Ambiente (Environment), histórico de operações, conexões, tutorial e versionamento (caso estejamos usando alguma ferramenta para versionamento de código como o git). A principal aba é a do ambiente, onde temos uma visualização rápida de todas as variáveis que estão carregadas no nosso ambiente. Aprenderemos mais sobre variáveis no decorrer do curso.
Painel do Console
Esse painel se encontra no lado inferior esquerdo da tela. Nela temos abas do console, terminal e de tarefas. Para os fins deste curso focaremos na aba de console. Ela nos permite interagir diretamente com o R, executando linhas de comando e obtendo os resultados instantaneamente.
Painel de Navegação
Esse painel fica no lado inferior direito. Nele temos uma interface para navegar pelos arquivos no seu computador (como o Windows Explorer que utilizamos normalmente). Também temos abas que nos permitem visualizar gráficos que foram gerados, pacotes que temos instalados e carregados e também a aba de ajuda de funções e pacotes.
Primeiras Operações e Primeiro Script
Agora que já nos familiarizamos com a interface do Rstudio, podemos começar a fazer nossas primeiras operações no R.
Funções matemáticas básicas
Umas das coisas mais básicas que podemos fazer em um script de programação é realizar operações matemáticas como somas, subtrações, divisões e multiplicações. Para isso utilizaremos os seguintes operadores:
Soma : +
Subtração: -
Multiplicação: *
Divisão: /
Podemos testar essas operações no console, digitando a operação desejada no console e apertando Enter.
Para facilitar a didática do curso uma versão básica do console está incluída no arquivo HTML e podemos executar os códigos aqui para acompanhar as aulas sem ter que instalar o R e RStudio.
# Este é o visual que um código em R tem# Linhas iniciadas por cerquilha(#) são comentários, ou seja, são linhas que# servem apenas para o operador humano que está lendo o código e não têm nenhuma# influência no fluxo do script e nem realizam nenhuma operação ou tarefa# Geralmente utilizamos linhas de comentários para explicar nosso raciocínio# e o que estamos fazendo a alguém que eventualmente vá ler nosso código1+23.5+0.000110-249.2-70.03452*34.5*25/2476/35
E assim são os resultados apresentados no console pela execução das linhas acima
[1] 3
[1] 3.5001
[1] 8
[1] -20.8345
[1] 6
[1] 9
[1] 2.5
[1] 13.6
[1] 6.5
[1] 4
Outras funções matemáticas
Além das operações matemáticas básicas, outras operações um pouco mais complexas podem ser úteis como:
Potenciação: ^
Divisão inteira: %/%
Resto da divisão inteira: %%
É chato lembrar essas operações mas vai ser útil, eu juro!
2^104^0.54%/%310%/%310%%55%%3
[1] 1024
[1] 2
[1] 1
[1] 3
[1] 0
[1] 2
Operações lógicas (booleanas)
Além de operações algébricas, podemos também fazer operações lógicas (booleanas).
Igual: ==
Maior: >
Menor: <
Maior ou Igual, Menor ou Igual: >= <=
E: &
Ou: |
Não: !
Diferente (não igual): !=
No R temos que as palavras TRUE e FALSE (tudo em maiúsculo mesmo) são palavras reservadas para os valores lógicos de verdadeiro e falso. Também podemos usar apenas T e F. Os valores TRUE e FALSE geralmente também são associados aos valores 1 e 0, respectivamente ou às ideias de ligado e desligado.
Palavras reservadas em uma linguagem de programação são palavras que não podemos usar normalmente em nossos códigos como nomes de variáveis, funções, objetos pois elas já estão reservadas para alguma funcionalidade da linguagem.
# Afirmação 1TRUE==FALSE# Afirmação 2FALSE==FALSE# Afirmação 3TRUE&FALSE# Afirmação 4T & T# Afirmação 5FALSE|FALSE# Repare que utilizar Apenas T ou apenas F funciona como se utilizássemos# a palavra inteira# Afirmação 6T | F# Afirmação 7!FALSE# Afirmação 8TRUE!=FALSE# Afirmação 91<2# Afirmação 102>=2# Afirmação 1115==15.0
Até o momento nós só executamos operações e já vimos o resultado delas impresso no console em seguida. Mas como faríamos para guardar resultados de operações e recuperar eles posteriormente (assim como fazemos com planilhas, por exemplo). Em linguagens de programação nós utilizamos variáveis para fazer esse trabalho.
Variáveis são a ferramenta que uma liguagem de programação dispõe para reservar espaços na memória do computador e armazenar informações nessa memória durante a execução de um programa.
As variáveis podem ser de vários tipos. Os principais tipos de variáveis em R são:
character (caractere/texto) onhecido como string em outras linguagens
numeric (números reais)
integer (números inteiros)
logical (booleanos: TRUE/FALSE)
factor (variáveis categóricas)
complex (números complexos)
Como atribuir e utilizar variáveis
Para utilizar variáveis geralmente começamos atribuindo algum valor para elas. Em R geralmente utilizamos <- como operador de atribuição. Assim, podemos armazenar valores em variáveis da seguinte forma:
# Aqui estamos simultaneamente criando uma variável chamada empresa e atribuindo# a ela o valor textual de Sicoob# Utilizamos valores de texto entre aspas ou aspas simples# "Sicoob" ou 'Sicoob'empresa <-"Sicoob"# Aqui podemos mostrar no console o valor que temos aramazenado na variávelempresa
[1] "Sicoob"
# Agora podemos utilizar o valor armazenado an variavel empresa em outras partes# do nosso script# paste é uma função que concatena texto# class# print é uma função que mostra valores em tela. Não se preocupe com funções no# momento pois aprenderemos mais sobre elas em breve.print(paste("Eu trabalho no", empresa))
[1] "Eu trabalho no Sicoob"
# Veja como a mensagem muda caso coloquemos outro valor na variável empresaempresa <-"Centro Cooperativo Sicoob"print(paste("Eu trabalho no", empresa))
[1] "Eu trabalho no Centro Cooperativo Sicoob"
Repare que a variável que criamos agora aparece no painel superior direito do RStudio.
## Variáveis numéricas# # Criando e atribuindo a uma variável chamada numero o valor 25.5numero <-25.5# Agora que temos esse valor armazenado, podemos fazer operações com elenumero *3+40.5
[1] 117
# Note que se atribuirmos outro valor, o resultado da operação mudanumero <-11.2numero *3+40.5
[1] 74.1
# Agora com números inteiros# Para definir explicitamente que um número será inteiro, utilizamos um L# ao final do númerocontagem <-1Lcontagem +2L
[1] 3
# Booleanos armazenam valores tipo Verdadeiro ou Falsoafirmacao <-TRUE&FALSEafirmacao
[1] FALSE
# Números complexos podem ser guardados em variáveis do tipo complex.# Como é um uso muito específico vai ficar apenas ilustrada aqui a # sintaxe dessas variáveis mas dificilmente a utilizaremos novamente# Para representar um número complexo utilizamos a notação usual de # uma parte real e uma imaginária, seguida do icomplicado <-3+4icomplicado +2+1i
[1] 5+5i
Agora vamos rapidamente avaliar os tipos das variáveis que criamos anteriormente.
# class é uma função que retorna qual a classe/categoria de um objetoclass(empresa)class(numero)class(contagem)class(afirmacao)class(complicado)
Agora vamos a alguns problemas que podemos ter ao criar variáveis em R e quais as boas práticas que devemos ter para evitar esses problemas.
R case sensitive, ou seja, diferencia letras maiúsculas de minúsculas. Então uma variável chamada idade, será diferente de uma chamada Idade, que será diferente de uma chamada IdAdE, como podemos verificar a seguir.
idade <-15Idade <-13idade == Idade
[1] FALSE
Outro problema que já citamos anteriormente é a questão das palavras reservadas. Como já vimos, TRUE é uma palavra reservada em R, então não podemos criar uma variável com esse nome.
Também não podemos utilizar espaço ou outros caracteres inválidos. Ou seja, não podemos criar uma variável chamada “minha idade”. Ao invés disso é recomendado utilizar sublinhado ( _ ) para separar o nome de variaveis com nome composto.
Tipagem de variáveis
R é uma linguagem de tipagem fraca e dinâmica. Em resumo, as variáveis em R podem mudar de tipo ao longo de um script que nós escrevemos, se assim desejarmos. Isso também permite que eventualmente façamos operações com variáveis de tipos diferentes. Isso pode nos trazer benefícios como uma maior agilidade e flexibilidade para criar nossos códigos. Porém, também há algumas desvantagens: temos que ter cuidado para não transformar variáveis incorretamente e inviabilizar alguma operação ou funcionalidade do nosso script.
Aqui um exemplo de como R lida dinamicamente com variáveis:
numero <-15.6inteiro <-2Lclass(numero)class(inteiro)inteiro <- numero + inteiroclass(inteiro)
[1] "numeric"
[1] "integer"
[1] "numeric"
Como podemos constatar, a variável inteiro foi convertida automaticamente para numeric quando fizemos a operação de soma.
Estruturas de Dados
Estruturas de dados são “esquemas” que a linguagem de programação usa para armazenar e organizar dados. As principais estruturas de dados em R são:
Vetores
Listas
Matrizes
DataFrames
Vamos exemplificá-los um a um
Vetores
Um vetor é basicamente um conjunto de dados indexados. O que isso significa? Que um vetor é uma coleção de dados onde podemos acessar cada dado individualmente através de um índice. Para criar um vetor em R basta colocar os valores que vão compô-lo separados por vírgula dentro de um c( ).
Vejamos como isso funciona:
# Vamos criar um vetor com nomes# Para criar um vetor em R utilizamcolegas <-c('Paulo', 'Marcelo', 'Nilo', 'Duda', 'Thiago')# Podemos agora imprimir o vetor colegas para verificar como ele ficouprint(colegas)
[1] "Paulo" "Marcelo" "Nilo" "Duda" "Thiago"
Para acessar cada membro individualmente, utilizamos colchetes após o número da variável com o índice do elemento que queremos acessar no vetor. O índice nada mais é que um número inteiro que indica a posição no vetor. R é indexado por 1, ou seja, o índice do primeiro elemento do vetor (Paulo) é 1. Isso parece óbvio mas há várias linguagens de programação que sãco indexadas em 0, ou seja, o primeiro elemento do vetor seria o de índice 0. Vamos ver na prática como acessar os elementos
# Como acessar os elementos 1 e 3 do vetorprint(colegas[1])print(colegas[3])# Também podemos listar vários elementos para acessar de uma vez ou mesmo# utilizar : para listar todos os elementos de um intervaloprint(colegas[c(2,3)])print(colegas[1:4])print(colegas[2:5])
Também temos a peculiaridade de que um vetor contém apenas elementos de mesmo tipo. Veja como ao tentar criar um vetor com texto e número, o R converte o número para texto para uniformizar os elementos.
Como vimos, o R acabou convertendo tanto os número inteiros quanto os reais para texto.
Vetores são tão úteis que vamos fazer um breve resumo de várias funções para utilizar com vetores (ainda veremos mais a fundo sobre funções, não se preocupe).
Lista de funções úteis para vetores
seq( ) : cria vetores com sequências númericas
rep( ) : cria vetores com elementos repetidos
length( ) : mede o comprimento de um vetor
unique( ) : retorna apenas valores únicos de um vetor
sum( ) : soma os valores do vetor
mean( ) : calcula a média do vetor
median( ) : calcula a mediana de um vetor
min( ) e max( ) : retorna o mínimo e o máximo
var( ) : calcula a variância
sd( ) : calcula o desvio padrão
%in% : é um operador que calcula se elementos de um vetor pertencem também a outro vetor
a utilização do %in% é como se fosse uma operação lógica
Vamos exemplificar:
# Cria um vetor usando o seq. Vamos criar um vetor começando em 1, terminando em 10# e indo de 1 em 1exemplo <-seq(from =1, to =10, by =1)# Vamos criar um vetor concatenando 3 cópias do primeiroexemplo2 <-rep(exemplo, times =3)print(exemplo)print(exemplo2)# Vamos utilizar esse vetor para exemplificar as demais funções# Qual o comprimento dos vetores exemplos?length(exemplo)length(exemplo2)# Quais os elementos únicos de exemplo2?unique(exemplo2)# Somasum(exemplo)# Médiamean(exemplo)# Medianamedian(exemplo)# Mìnimomin(exemplo)# Máximomax(exemplo)# Variânciavar(exemplo)# Desvio Padrãosd(exemplo)# Só conferindo que de fato o desvio padrão é a raiz quadrada da variânciavar(exemplo)^0.5# Testa se os elementos c(1,2,3,100) estão no vetor exemplo# Observe que obtemos como resposta um vetor lógico com um valor# Para cada elemento do vetor testadoc(1,2,3,100) %in% exemplo# Também podemos fazer o mesmo teste apenas com um valor4%in% exemplo123%in% exemplo
R é uma linguagem que trabalha de maneira vetorial. Isso é extremamente potente para realizar operações matemáticas pois podemos aplicar uma operação a um vetor inteiro de uma vez, sem dificuldades. Podemos fazer isso com todas as operações matemáticas e lógicas que já vimos anteriormente, gerando como resultado também um vetor. Vamos exemplificar:
# Vamos exemplificar operações com vetores utilizando o vetor de exmeplo anterior# e criando um novo vetor com valores lógicosexemplo_logico <-c(T,F,T,F,F,F,T)# Somar 2 vetores resulta nas somas de seus elementos individuais# o mesmo ocorre com a subtraçãoexemplo + exemplo# podemos também somar ou subtrair um valor a todos os elementos do vetorexemplo +3exemplo -1# Multiplicar um vetor pelo outro resulta na multiplicação vetorial# No caso a seguir seria como elevar cada elemento ao quadradoexemplo * exemplo# Também podemos multiplicar ou dividir por constantesexemplo /2exemplo *3# POdemos realizar todas as operações lógicas que conhecemos com o vetor de # valores lógicosexemplo_logico & Texemplo_logico | T
E uma última curiosidade/truque que pode ser muito útil. Já foi mencionado que os valores lógicos TRUE e FALSE também podem ser interpretados como 1 e 0, respectivamente. O que acontece se utilizarmos funções como sum e mean em um vetor de valores lógicos?
# Calculando a soma de valores lógicossum(exemplo_logico)
[1] 3
# Calculando a média de valores lógicosmean(exemplo_logico)
[1] 0.4285714
Quando utilizamos essas funções em um vetor booleano, o R considera valores TRUE como 1 e FALSE como 0 e realiza as funções matemáticas normalmente. Observem então que o sum( ) de um vetor lógico então é equivalente a contar quantos valores TRUE nós temos nesse vetor.
Listas
Já uma lista é um conjunto de elementos de tipos diferentes. Para criar uma lista colocamos nossos itens separados por vírgula dentro de list( ). Para acessá-los, fazemo de modo similar aos vetores, utilizando os colchetes. A diferença é que dentro de uma lista agora podemos dar nome aos nosso objetos e acessar esses objetos utilizando seus nomes além dos índices.
Para acessar um elemento pelo seu nome podemos utilizar a sintaxe de $nome ou os colchetes
Vejamos exemplos de tudo isso a seguir para ficar mais claro:
# Utilizando list() para criar uma listafuncionario <-list("Paulo", "Analista", 34, 15)# Podemos acessar os itens pelo índice, como fizemos anteriormente nos vetoresfuncionario[1]funcionario[3]# Ao invés de utilizar só os índices podemos também nomear os elementoscadastro <-list(nome ="Paulo", cargo ="Analista", idade =34, aniversario =15)# Agora, para acessar os elementos, podemos utilizar tanto o índice quanto # o nome e obter o mesmo resultadocadastro[1]cadastro$nomecadastro[3]cadastro$idade
Matrizes são estruturas bidimensionais (linhas e colunas) que armazenam elementos do mesmo tipo. Utilizamos matrix( ) para criar uma matriz. Também especificamos a quantidade de linhas e colunas que queremos na nossa matriz. Para acessar os elementos de uma matriz nós utilizamos colchetes com os índices de linha e coluna separados por vírgula. (É só lembrar de como aprendemos matrizes em matemática na escola). Vamos ao exemplo:
# Utilizando matrix( ) para criar uma matriz# No primeiro campo dizemos que queremos popular a matriz com os números 1 a 12# Nos próximos campos especificamos quantas linhas (nrow) e colunas (ncol) queremosmatriz <-matrix(1:12, nrow =4, ncol =3)# Mostrando como fica a matrizprint(matriz)# Acessando elementos específicos# Aqui queremos acessar o elemento da linha 1 e coluna 2matriz[1,2]# Também podemos utilizar utilizar um vetor com os índices que queremos e# selecionar vários elementos# Aqui queremos selecionar os elementos da primeira e terceira linhas # que estão na segunda e terceira colunasmatriz[c(1,3), c(2,3)]# Também podemos omitir o número, utilizando um espaço vazio para listar# todos os elementos daquela dimensão. Por exemplo aqui vamos selecionar# todos os elementos da segunda e terceira colunasmatriz[ , c(2,3)]# E aqui, todos os elementos da primeira linhamatriz[1, ]
Dataframes são tabelas de dados onde cada coluna pode armazenar um tipo de dado diferente. Um DataFrame remete a uma planilha no excel. Essa estrutura é a mais utilizada para nossas tarefas pois ela é uma estrutura essencial e versátil para manipulação de dados.
Internamente o R cria um DataFrame fazendo uma lista de vetores, então algumas das coisas que acabamos de ver já vão ser úteis para manipular DataFrames.
Para criar um dataframe utilizamos data.frame( ) e listamos dentro os vetores com os dados que vão ser armazenados. (No momento fazemos isso de maneira manual apenas para fins didáticos, na prática geralmente lemos DataFrames de arquivos ou outras fontes ou utilizamos outras maneiras mais ágeis de criá-los)
Vamos exemplificar como criar um DataFrame e como selecionar dados nele:
# Utilizando data.frame( ) para criar um DataFrame# Vamos utilizar um formato um pouco diferente no código para fins de organização # e legibilidade de quem eventualmente for ler o nosso código (até nós mesmos).# O efeito prático vai ser o mesmo que teria se o código a seguir fosse escrito # em uma só linha# Vamos criar um DataFrame com algumas linhas como se fossem o cadastro # de um curso para usarmos daqui em diantedf <-data.frame(nomes =c("Paulo", "Pedro", "Mariana","Marcus","Clara"),genero =c("H","H","M","H","M"),idades =c(34,50,34,33,26),turma =c("Avançada","Intermediária","Avançada","Intermediária","Iniciante"),notas =c(5.6,7.5,8.4,4.3,3.2),mensalidade_em_dia =c(T,F,T,T,F))# E agora visualizamos o que acabamos de criarprint(df)
nomes genero idades turma notas mensalidade_em_dia
1 Paulo H 34 Avançada 5.6 TRUE
2 Pedro H 50 Intermediária 7.5 FALSE
3 Mariana M 34 Avançada 8.4 TRUE
4 Marcus H 33 Intermediária 4.3 TRUE
5 Clara M 26 Iniciante 3.2 FALSE
Aqui um jeito um pouco mais organizado para facilitar a visualização do que acabamos de criar.
nomes
genero
idades
turma
notas
mensalidade_em_dia
Paulo
H
34
Avançada
5.6
TRUE
Pedro
H
50
Intermediária
7.5
FALSE
Mariana
M
34
Avançada
8.4
TRUE
Marcus
H
33
Intermediária
4.3
TRUE
Clara
M
26
Iniciante
3.2
FALSE
Manipulação de DataFrames
Funções úteis
Agora vamos aprender como utilizar DataFrames e as principais funções que úteis para lidar com DataFrames
head( ) : mostra as primeiras linhas
podemos passar um argumento numérico para especificar quantas linhas queremos visualizar: head(df, linhas)
tail( ) : mostra as últimas linhas
podemos passar um argumento numérico para especificar quantas linhas queremos visualizar: tail(df, linhas)
nrow( ) : conta quantas linhas tem o DataFrame
ncol( ) : conta quantas colunas tem o DataFrame
dim( ) : lista as duas dimensões do DataFrame (linhas e colunas)
names( ) e colnames( ) : lista os nomes das colunas
rownames( ) : lista os nomes das linhas
str( ) : mostra a estrutura do DataFrame, quais os tipos das colunas e uma amostra dos elementos de cada coluna
summary( ) : gera um resumo estatístico do DataFrame
# As funções head() e tail() listam, caso não seja especificado, 5 linhas por# padrão. Não vou colocar aqui para não poluir a apostila e também porque o# nosso DataFrame tem apenas 5 linhas, ou seja, o resultado de head e tail seria# o mesmo. Mais a frente utilizaremos essas funçõesnrow(df)ncol(df)dim(df)names(df) colnames(df)rownames(df)str(df)summary(df)
[1] 5
[1] 6
[1] 5 6
[1] "nomes" "genero" "idades"
[4] "turma" "notas" "mensalidade_em_dia"
[1] "nomes" "genero" "idades"
[4] "turma" "notas" "mensalidade_em_dia"
[1] "1" "2" "3" "4" "5"
'data.frame': 5 obs. of 6 variables:
$ nomes : chr "Paulo" "Pedro" "Mariana" "Marcus" ...
$ genero : chr "H" "H" "M" "H" ...
$ idades : num 34 50 34 33 26
$ turma : chr "Avançada" "Intermediária" "Avançada" "Intermediária" ...
$ notas : num 5.6 7.5 8.4 4.3 3.2
$ mensalidade_em_dia: logi TRUE FALSE TRUE TRUE FALSE
nomes genero idades turma
Length:5 Length:5 Min. :26.0 Length:5
Class :character Class :character 1st Qu.:33.0 Class :character
Mode :character Mode :character Median :34.0 Mode :character
Mean :35.4
3rd Qu.:34.0
Max. :50.0
notas mensalidade_em_dia
Min. :3.2 Mode :logical
1st Qu.:4.3 FALSE:2
Median :5.6 TRUE :3
Mean :5.8
3rd Qu.:7.5
Max. :8.4
Seleção e filtragem de elementos em DataFrames
Além dos modos que já vimos para selecionar dados em listas e matrizes, dispomos de mais jeitos para selecionar dados em DataFrames.
Para Selecionar Colunas
$coluna : assim como fizemos nas listas
df[[“nome da coluna”]] : tem o mesmo resultado da forma anterior mas é mais prática para scripts iterativos (mais sobre isso posteriormente)
df[ , “coluna”] ou df[ , número da coluna] : aqui utilizamos uma notação parecida com a de matriz para selecionar a coluna. Podemos selecionar a coluna pelo nome ou pelo seu índice (posição dela no DataFrame)
subset(df, select = c(coluna1, coluna2)) : aqui utilizamos a função subset para listar uma ou mais colunas. Passamos para a função o DataFrame que queremos utilizar e um vetor com as colunas a serem selecionadas
Agora vamos ilustrar todos esses modos de selecionar colunas em um DataFrame:
# Selecionando apenas a colunas de nomes de todos os modos que vimos acimadf$nomesdf[["nomes"]]df[, "nomes"]# Há uma diferença técnica entre os jeitos de selecionar.# Como podemos ver agora, os jeitos que utilizamos acima nos retornaram# um vetor com os nomes. O método utilizando subset retorna outro DataFramesubset(df, select ="nomes")# Também podemos usar essa sintaxe de seleção para alterar ou incluir # dados no DataFrame# vamos criar uma nova coluna no DataFrame que diz se os alunos são bolsistasdf$bolsista <-c(T,F,F,T,F)# Também podemos fazer isso para substituir ou alterar uma colunadf[["nomes"]] <-c("Paulo", "Pedro", "Mariana","Marcus","Luiza")# Vamos visualizar como ficou o DataFrame com as alteraçõesprint(df)
nomes genero idades turma notas mensalidade_em_dia bolsista
1 Paulo H 34 Avançada 5.6 TRUE TRUE
2 Pedro H 50 Intermediária 7.5 FALSE FALSE
3 Mariana M 34 Avançada 8.4 TRUE FALSE
4 Marcus H 33 Intermediária 4.3 TRUE TRUE
5 Luiza M 26 Iniciante 3.2 FALSE FALSE
Para Selecionar linhas ou conjuntos de elementos
df[ linhas, ] : seleciona as linhas listadas. Funciona como fizemos para matriz, listando os elementos que queremos selecionar
df[“nome da linha”, ] : seleciona as linhas pelos nomes, caso tenhamos atribuido nomes a elas
Vamos visualizar como selecionar linhas:
# Selecionando linhas# Selecionando a primeira linhadf[1, ]# Selecionando a primeira e a quarta linhasdf[c(1,4),]# Selecionando as linhas de 1 a 3df[1:3, ]
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
Paulo
H
34
Avançada
5.6
TRUE
TRUE
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
1
Paulo
H
34
Avançada
5.6
TRUE
TRUE
4
Marcus
H
33
Intermediária
4.3
TRUE
TRUE
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
Paulo
H
34
Avançada
5.6
TRUE
TRUE
Pedro
H
50
Intermediária
7.5
FALSE
FALSE
Mariana
M
34
Avançada
8.4
TRUE
FALSE
Além de tudo que vimos, também podemos selecionar linhas com base em condições com as seguintes sintaxes:
df[condição, ] : seleciona linhas que satisfazem a condição listada
subset(df, condição) : mesma coisa mas devolve um DataFrame
# Agora podemos começar a fazer seleções mais interessantes#Vamos selecionar apenas as mulheres# Explicando o que está acontecendo:# Como já vimos anteriormente, df$genero nos traz um vetor com os elementos# que estão na coluna genero no DataFrame# Como também já vimos antes, podemos aplicar uma condição lógica a um vetor# e obter um vetor de valores lógicos de volta. Agora o pulo do gato: também# podemos selecionar linhas com base em um vetor lógico, onde serão selecionadas# as linhas onde o valor seja TRUE. Juntando tudo isso, temos a seguinte linha de# código, que nos retorna apenas as linhas onde genero seja igual a Mdf[df$genero =="M",]# Agora, supondo uma média 6, vamos selecionar apenas os alunos aprovados# e salvá-los em outro DataFramedfaprovados <- df[df$notas >=6, ]print(dfaprovados)# Agora vamos separar também os reprovados em outro DataFramedfreprovados <- df[df$notas <6, ]# Também podemos utilizar operadores lógicos para filtrar com base em# mais de uma condição. Vamos usar o conectivo E para filtrar alunos# com genero masculino e nota maior ou igual a 7df[df$genero =="H"& df$notas >=7, ]# Agora vamos filtrar alunos de turma intermediária e cujas mensalidades# estejam em dia. Repare que não precisamos fazer uma proposição lógica# sobre o vetor mensalidade_em_dia já que ele já é um vetor apenas com# valores lógicosdf[df$turma =="Intermediária"& df$mensalidade_em_dia, ]
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
3
Mariana
M
34
Avançada
8.4
TRUE
FALSE
5
Luiza
M
26
Iniciante
3.2
FALSE
FALSE
nomes genero idades turma notas mensalidade_em_dia bolsista
2 Pedro H 50 Intermediária 7.5 FALSE FALSE
3 Mariana M 34 Avançada 8.4 TRUE FALSE
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
2
Pedro
H
50
Intermediária
7.5
FALSE
FALSE
nomes
genero
idades
turma
notas
mensalidade_em_dia
bolsista
4
Marcus
H
33
Intermediária
4.3
TRUE
TRUE
E por fim, também temos jeitos de juntar DataFrames e adicionar mais colunas ou linhas a eles:
cbind( ) : de column bind, adiciona junta Data frames no sentido horizontal, ou seja, acrescenta o segundo DataFrame como colunas do primeiro
Portanto, para que essa operação funcione, precisamos que os DataFrames tenham o mesmo número de linhas
rbind( ) : de row bind, junta DataFrames no sentido vertical, ou seja, acrescenta o segundo DataFrame como linhas do primeiro
Portanto, para que essa operação funcione, precisamos que os DataFrames tenham o mesmo número de colunas
Vamos exemplificar:
# Vamos utilizar rbind( ) para unir novamente os DataFrames de aprovados# e reprovados, reconstituindo o DataFrame original# Passamos como argumento da função rbind os dataframes que queremos unirdf2 <-rbind(dfaprovados,dfreprovados)# Verificando que reconstituimos o DataFrame originalprint(df2)# Agora vamos acrescentar uma nova coluna de informações ao DataFrame reconstruído# usando cbind( ). Vamos gerar um vetor que diz se os alunos foram aprovados# e adicionar essa informação# Detalhe, aqui eu estou sobrescrevendo o objeto original df2 e substituindo# ele pela sua versão com a nova colunadf2 <-cbind(df2, aprovado =c(T,T,F,F,F))# print(df2)
nomes genero idades turma notas mensalidade_em_dia bolsista
2 Pedro H 50 Intermediária 7.5 FALSE FALSE
3 Mariana M 34 Avançada 8.4 TRUE FALSE
1 Paulo H 34 Avançada 5.6 TRUE TRUE
4 Marcus H 33 Intermediária 4.3 TRUE TRUE
5 Luiza M 26 Iniciante 3.2 FALSE FALSE
nomes genero idades turma notas mensalidade_em_dia bolsista
2 Pedro H 50 Intermediária 7.5 FALSE FALSE
3 Mariana M 34 Avançada 8.4 TRUE FALSE
1 Paulo H 34 Avançada 5.6 TRUE TRUE
4 Marcus H 33 Intermediária 4.3 TRUE TRUE
5 Luiza M 26 Iniciante 3.2 FALSE FALSE
aprovado
2 TRUE
3 TRUE
1 FALSE
4 FALSE
5 FALSE
Essas não são as únicas formas nem as mais rápidas de manipular dados em R. No próximo módulo vamos ver modos ainda mais rápidos e potentes, mas por enquanto o que aprendemos já é bastante útil.
Primeiro Conjunto de Exercícios
Agora que já vimos bastante conteúdo e já sabemos o básico de objetos, estruturas de dados e uma série de funções úteis para manipular dados, vamos fazer nossos primeiros exercícios em código
Exercício 1
Crie um vetor chamado exercicio1 contendo a sequência de números pares de 2 a 20
Adicione 3 a todos os elementos desse vetor
Multiplique esse vetor por 5
Imprima o primeiro elemento desse vetor
Imprima os últimos 3 elementos desse vetor
Crie um novo vetor chamado final1 que tenha apenas os primeiros 5 elementos do vetor exercicio1 após as manipulações que fizemos anteriormente
Utilize o bloco de código a seguir para fazer o exercício. O código vai corrigir apenas o resultado final do item 6 da questão, ou seja, vai avaliar apenas o que está no vetor final1.
Exercício 2
Agora vamos trabalhar com DataFrames. Já está carregado para vocês um DataFrame chamado alunos que simula informações sobre alunos de um curso. Vamos fazer alguns exercícios com esse DataFrame
Utilize o console abaixo para explorar o DataFrame. Lembre das funções que acabamos de estudar e que são muito úteis para avaliar a estrutura de um DataFrame e gerar um resumo de seu conteúdo.
Quais os nomes dos alunos nas linhas 3 e 4 do DataFrame? Responda com um vetor para que a resposta seja avaliada corretamente.
Qual a maior nota entre os alunos?
Quantos alunos têm 25 anos ou mais?
Dica! As função length, sum ou nrow podem ser úteis. Há como resolver esse exercício utilizando qualquer uma dessas
Liste os alunos que são bolsistas e tiveram nota abaixo da média.
Dica: não precisamos calcular e guardar a média antes, embora essa seja uma solução possível. Podemos calcular a média e filtrar simultaneamente
Considere que a média para aprovação nessa faculdade é 6.5. Crie um novo DataFrame apenas com os alunos aprovados
Vamos supor que os alunos que tiverem notas até 2 ponto abaixo da média de notas da turma e não conseguiram a média para passar ( 6.5 ) podem ficar de recuperação no fim do semestre. Crie um DataFrame apenas com os alunos em recuperação
Agora vamos adicionar um novo aluno ao nosso DataFrame de alunos. utilize a seguinte lista que descreve o novo aluno e o junte ao DataFrame de alunos.
Agora vamos adicionar mais uma característica dos alunos. Crie um vetor que vai dizer se os alunos são de cursos de humanas. Para isso considere que são de humanas os cursos de Historia, Filosofia e Sociologia. O vetor resultante deve ter valor TRUE para alunos desses cursos e FALSE para alunos de outros cursos. Para esse exercício partimos do DataFrame correto do exercício anterior, que já está carregado no ambiente. Portanto, basta criar o vetor e juntar como uma nova coluna no DataFrame alunos.
Controle de Fluxo
Até aqui, nós só executamos linhas de código em sequência, considerando que tudo ocorre de maneira linear e previsível no nosso código. Mas e se tivermos que tomar decisões? Se tivermos que realizar tarefas diferentes de acordo com algum critério? Para isso serve o controle de fluxo em código de programação.
As principais estruturas utilizadas para controle de fluxo em R (assim como em quase todas as linguagens de programação) são o if-else, for e while.
If else
A estrutura if ou if else verifica uma condição e executa o código apenas se essa condição for satisfeita.
Sua sintaxe é a seguinte:
if(condicao){ código a ser executado}
No exemplo acima, nós preencheríamos os parenteses com a nossa condição lógica, ou seja, utilizamos alguma expressão que vai ter como resultado um TRUE ou FALSE. O código entre chaves só será executado caso a condição seja verdadeira. Aqui um exemplo de aplicação. Experimente mudar a nota e ver os diferentes resultados
Podemos também expandir a sintaxe do if utilizando else if ou só else. O que isso significa? Podemos colocar todas as condições que quisermos avaliar. A sintaxe acrescentado o else if ficaria assim:
if(condicao){ código a ser executado caso a condição 1 seja verdadeira}elseif(condicao2) { código a ser executado caso a condição 2 seja verdadeira}elseif(condicao3) { código a ser executado caso a condição 3 seja verdadeira}e por aí vai...
Expandindo o exemplo anterior:
Além disso podemos também acrescentar ao final um bloco apenas com else para capturar todas as situações restantes que não foram descritas nas condições com if else.
# Exemplo de if else simplesif(condicao){ código a ser executado caso a condição 1 seja verdadeira}else{ código a ser executado caso a condição 1 não seja verdadeira}# Exemplo de if else com mais de uma condiçãoif(condicao){ código a ser executado caso a condição 1 seja verdadeira}elseif(condicao2) { código a ser executado caso a condição 2 seja verdadeira}else{ código a ser executado caso nem a condição 1 nem a 2 sejam verdadeiras}
ifelse vetorizado
Também temos em R uma aplicação vetorizada da lógica if-else. O que isso significa? Temos uma função que aplica resultados de uma condição tipo if-else em um vetor inteiro de uma vez. Seria algo como utilizar a função SE no excel em uma coluna inteira de uma vez sem precisar arrastar. A sua sintaxe é simples, como é uma função, temos que colocar argumentos entre parênteses para descrever o que queremos fazer. No caso do ifelse seria: ifelse( condição, resultado caso verdadeira, resultado caso negativa)
Vamos ilustrar:
# Vamos criar um vetor que simula as notas de diversos alunosnotas <-c(1, 5.5, 7, 9, 2.5, 3, 7.5, 0, 10, 8.5, 2)# E supondo que a média é 5, vamos, de uma vez só, criar um vetor# que diz se o aluno foi aprovado ou nãoresultado <-ifelse(notas >=5, "Aluno Aprovado!", "Aluno Reprovado =(")print(resultado)
A estrutura while executa um trecho de código enquanto uma condição for verdadeira. Estruturas de repetição como essa também são chamadas de laços (do inglês loop). Como essa estrutura fica repetindo o código enquanto a condição for verdadeira, temos que nos certificar de que o bloco de código que está dentro do laço atualiza a condição de alguma forma para que em algum momento ela deixe de ser verdadeira.
Oras, como assim? Se não fizermos isso o programa vai ficar repetindo aquele código para sempre? Sim, é exatamente isso. Caso não implementemos o laço while de maneira correta, corremos o risco de travar nosso programa, por isso prestem sempre atenção ao utilizar essa estrutura.
A sintaxe para o while é a seguinte:
while(condicao){ código a ser executado código para atualizar a condição}
For
O laço for é similar ao while. Ele também executa um bloco de código repetidamente. A diferença é que no laço for nos sabemos quantas vezes o laço vai ser executado e já definimos um vetor, lista ou sequência para ele percorre. Sua sintaxe é a seguinte:
for (indice in vetor){ código a ser executado}
Para cada execução do laço o indice “anda” uma posição no vetor. Vamos ilustrar:
# Percorrendo um vetor de 1 a 6 for(i in1:6){print(paste("Estou na posição ", i))}# Os vetores utilizados no laço não precisam ser numéricosnomes <-c("Paulo", "Maria","Mariana","Pedro","Daniel","Luiza","Marcus")for(i in nomes){print(paste("Estou no nome: ", i))}
[1] "Estou na posição 1"
[1] "Estou na posição 2"
[1] "Estou na posição 3"
[1] "Estou na posição 4"
[1] "Estou na posição 5"
[1] "Estou na posição 6"
[1] "Estou no nome: Paulo"
[1] "Estou no nome: Maria"
[1] "Estou no nome: Mariana"
[1] "Estou no nome: Pedro"
[1] "Estou no nome: Daniel"
[1] "Estou no nome: Luiza"
[1] "Estou no nome: Marcus"
Comandos auxiliares
Também dispomos de 2 comandos auxiliares para incorporar nas estruturas de laços:
break: é um comando que interrompe a execução de um laço
next: é um comando que pula para a próxima execução do laço
Exemplificando:
# Vamos fazer um código com while que só para quando a soma dos dados for 8soma <- Twhile(soma){# Sorteia 2 número de 1 a 6 para simular dados e já soma os dados soma <-sum(sample(c(1,2,3,4,5,6),size =2, replace = T))# Imprime o valor da soma caso não seja o valor inicialif(soma ==8){print("A soma deu 8, vou parar!")break }print(paste("Ainda não! Soma = ", soma))}# Agora exemplo de um laço com next# Vamos fazer um laço for que, apesar de percorrer todos os números de# 1 a 15, só imprime os números paresfor(i in1:15){# Falei que o resto da divisão inteira eventualmente seria útil!# Explicando: o resto da divisão inteira de um número par por 2 será# sempre 0, ou seja, esse é um jeito fácil de verificar se um número é par# ou ímpar.if(i %%2==1){next }print(paste("O número",i,"é par."))}
[1] "Ainda não! Soma = 5"
[1] "A soma deu 8, vou parar!"
[1] "O número 2 é par."
[1] "O número 4 é par."
[1] "O número 6 é par."
[1] "O número 8 é par."
[1] "O número 10 é par."
[1] "O número 12 é par."
[1] "O número 14 é par."
Funções
Anteriormente na apostila já utilizamos algumas funções. Vamos agora formalizar nosso entendimento sobre o que são funções, como utilizá-las e como criar nossas próprias funções. Para ficar claro, até agora usamos funções como print, seq, sum, mean etc. Olhando no material do curso até aqui, toda vez que abrimos e fechamos parênteses. Ao criar uma função podemos também definir argumentos (ou parâmetros) que essa função vai receber para trabalhar. Por exemplo, ao utilizar a função seq( ) para criar um vetor com sequências, passamos 3 argumentos para a função: o primeiro dizia onde a sequência se iniciaria, o segundo, onde ela terminaria e o terceiro de quantos em quantos números ela andaria. Ao criar nossas próprias funções, Podemos definir quantos argumentos quisermos, inclusive nenhum. A sintaxe para definir uma função em R é a seguinte:
nome_da_funcao <-function(argumentos){ codigo da funçãoreturn( )}
O return no final da função diz que encerramos sua execução e devemos devolver/retornar esse valor ao programa.
Vamos exemplificar como seria uma a definição e o uso de uma função que diz se um número é par e retorna TRUE caso seja e FALSE do contrário ( é um exemplo bobo porém clássico da programação) :
e_par <-function(numero){if(numero %%2==0){return(TRUE) } else {return(FALSE) }}# Imprime os resultados da nossa funçãoe_par(246)e_par(15)# Também podemos guardar os resultados da nossa função# em um objetoa <-e_par(15)print(a)
[1] TRUE
[1] FALSE
[1] FALSE
Segundo Conjunto de Exercícios
Agora que avançamos mais com o conteúdo, vamos fazer alguns exercícios para consolidar:
Utilizando a seguinte função, que vai gerar um vetor aleatório de 15 notas de 0 a 10
notas <-runif(15, min =0, max =10)
Faça um laço for que vai percorrer todo o vetor imprimindo se o aluno foi aprovado ou não (média 5).
Utilizando a função runif( ) como foi demonstrada anteriormente, faça um laço while que vai, a cada iteração: gerar um vetor de 15 notas, calcular a sua média e só vai parar quando essa média for maior que 5.75
Faça um laço for que vai percorrer os números de 1 a 50 e se comportar da seguinte maneira:
Imprimir “Fizz” quando um número for múltiplo de 3
Imprimir “Buzz” quando um número for múltiplo de 5
Imprimir “FizzBuzz” quando um número for múltiplo de 15
Refaça o exercício anterior definindo antes uma função chamada fizz_buzz que se comporta como o descrito no exercício anterior
Manipulação de Dados com dplyr
O que é o Dplyr?
O Dplyr é um pacote ( um pacote é basicamente um conjunto de funções para implementar novas funcionalidades na linguagem de programação). O dplyr implementa várias funções úteis para manipular dados e um operador novo que faz com que nosso código fique muito mais organizado e legível quando estamos mexendo com dados.
As principais funções do dplyr são:
select() - serve para selecionar colunas
arrange() - ordena as linhas segundo os critérios que você definir
filter() - filtra linhas
mutate() - cria/modifica colunas
group_by() - agrupa a base
summarise() - resume a base (geralmente utilizado em conjunto com o group_by( )
Essas não são as únicas funções mas são as essenciais para um contexto de iniciantes em programação. Se tiver curiosidade de saber mais, acesse https://dplyr.tidyverse.org/ , a página oficial desse pacote (em inglês). Vamos utilizar um dataframe de alunos parecido com o que já utilizamos no primeiro exercício.
O select serve para selecionar colunas. Vamos ilustrar seu uso:
# Vamos selecionar apenas as colunas de nome e idade# Já aprendemos a fazer algo do tipo:head(alunos[, c("nome", "idade")])
nome
idade
Ana
22
Paulo
25
Maria
19
Joao
23
Carla
21
Lucas
20
# Vamos utilizar o select para selecionar apenas as colunas de nome e idade# Com o select faríamos o seguintehead(select(alunos, nome, idade))
nome
idade
Ana
22
Paulo
25
Maria
19
Joao
23
Carla
21
Lucas
20
# com o select também podemos utilizar o - para "remover" uma coluna# Isso seleciona todas as colunas do dataframe menos a bolsistahead(select(alunos, -bolsista))
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
uf
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
SP
Paulo
Santos
25
Beatriz
Contabilidade
6.0
5.5
5.7
RJ
Maria
Oliveira
19
Carla
Contabilidade
9.2
5.6
5.5
MG
Joao
Souza
23
Daniela
Fisica
5.5
6.8
2.2
BA
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
RS
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
SP
# Também podemos utilizar o : para selecionar intervalos, assim como já fizemos# Seleciona as colunas de nome até nota1head(select(alunos, nome:nota1))
nome
sobrenome
idade
nome_mae
curso
nota1
Ana
Silva
22
Ana
Matematica
8.5
Paulo
Santos
25
Beatriz
Contabilidade
6.0
Maria
Oliveira
19
Carla
Contabilidade
9.2
Joao
Souza
23
Daniela
Fisica
5.5
Carla
Lima
21
Eduarda
Letras
7.8
Lucas
Pereira
20
Fernanda
Quimica
8.0
Também temos no dplyr várias funções auxiliares para facilitar as seleções com base em padrões nos nomes das colunas.
starts_with(): para colunas que começam com um texto padrão
ends_with(): para colunas que terminam com um texto padrão
contains(): para colunas que contêm um texto padrão
Exemplificando:
# Vamos selecionar apenas as colunas de notas# Poderíamos fazer assim já que as colunas são consecutivashead(select(alunos, nota1:nota3))
nota1
nota2
nota3
8.5
1.2
8.2
6.0
5.5
5.7
9.2
5.6
5.5
5.5
6.8
2.2
7.8
7.0
3.8
8.0
3.3
3.9
# ouhead(select(alunos, starts_with("nota")))
nota1
nota2
nota3
8.5
1.2
8.2
6.0
5.5
5.7
9.2
5.6
5.5
5.5
6.8
2.2
7.8
7.0
3.8
8.0
3.3
3.9
# Vamos selecionar apenas as colunas que contém primeiros nomeshead(select(alunos, starts_with("nome")))
nome
nome_mae
Ana
Ana
Paulo
Beatriz
Maria
Carla
Joao
Daniela
Carla
Eduarda
Lucas
Fernanda
# E agora, vamos selecionar colunas que contenham alguma informação de nome# seja nome ou sobrenomehead(select(alunos, contains("nome")))
nome
sobrenome
nome_mae
Ana
Silva
Ana
Paulo
Santos
Beatriz
Maria
Oliveira
Carla
Joao
Souza
Daniela
Carla
Lima
Eduarda
Lucas
Pereira
Fernanda
arrange ()
A função arrange serve para ordernar as linhas segundo os critérios que escolhermos. Por padrão o ordenamento é crescente mas podemos utilizar a função desc( ) para realizar uma ordenação descrescente. Podemos ordenar por tantas colunas quanto quisermos. Vamos exemplificar:
# Vamos ordernar os alunos por ordem crescente de nomehead(arrange(alunos, nome))
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
Ana
Almeida
22
Isabela
Direito
9.0
9.2
6.8
FALSE
MG
Andre
Silva
24
Patricia
Contabilidade
7.0
4.7
4.9
FALSE
BA
Andre
Lima
25
Sabrina
Estatistica
8.2
4.1
7.1
FALSE
RS
Camila
Souza
22
Rafaela
Letras
6.3
3.0
4.1
TRUE
SP
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
TRUE
RS
# Agora, ordernar por ordem decrescente de idadehead(arrange(alunos, desc(idade)))
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Roberto
Martins
30
Natalia
Filosofia
5.9
3.6
2.4
FALSE
RJ
Thiago
Carvalho
28
Larissa
Psicologia
7.2
7.5
7.1
FALSE
SP
Pedro
Costa
27
Helena
Economia
6.5
1.6
3.1
TRUE
RJ
Felipe
Costa
27
Vitoria
Estatistica
6.7
7.2
9.0
FALSE
RJ
Marcos
Nascimento
26
Juliana
Medicina
5.8
10.0
9.1
TRUE
BA
Paulo
Santos
25
Beatriz
Contabilidade
6.0
5.5
5.7
FALSE
RJ
# Podemos ordernar por mais de uma coluna e com critérios de ordenamento diferenteshead(arrange(alunos, nome, desc(nota1)))
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Ana
Almeida
22
Isabela
Direito
9.0
9.2
6.8
FALSE
MG
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
Andre
Lima
25
Sabrina
Estatistica
8.2
4.1
7.1
FALSE
RS
Andre
Silva
24
Patricia
Contabilidade
7.0
4.7
4.9
FALSE
BA
Camila
Souza
22
Rafaela
Letras
6.3
3.0
4.1
TRUE
SP
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
TRUE
RS
Pipe
O pipe é um operador que faz com que as sequências de operações em dplyr sejam claras e legíveis. Ele basicamente passa o resultado de uma função para a próxima função. Dessa forma, podemos declarar nossas operações em sequência. Podemos utilizar o pipe com %>% ou |> . A utilização do |> é a mais recomendada atualmente pois foi implementada nativamente no R e é a que vamos adotar para o curso.
Vamos a um exemplo para ilustrar o funcionamento do pipe com as funções do dplyr que já vimos
# Vamos combinar algumas coisas que já vimos# vamos selecionar no dataframe alunos apenas as colunas de nome e notas# ordenar por nome crescente e por nota1 decrescentehead(arrange(select(alunos, nome, starts_with("nota")), nome, desc(nota1)))
nome
nota1
nota2
nota3
Ana
9.0
9.2
6.8
Ana
8.5
1.2
8.2
Andre
8.2
4.1
7.1
Andre
7.0
4.7
4.9
Camila
6.3
3.0
4.1
Carla
7.8
7.0
3.8
# Conseguimos fazer o que queríamos, porém o nosso código está começando a ficar# Difícil de entender# Vamos tentar a mesma operação usando pipealunos |>select(nome, starts_with("nota")) |>arrange(nome, desc(nota1)) |>head()
nome
nota1
nota2
nota3
Ana
9.0
9.2
6.8
Ana
8.5
1.2
8.2
Andre
8.2
4.1
7.1
Andre
7.0
4.7
4.9
Camila
6.3
3.0
4.1
Carla
7.8
7.0
3.8
Podemos ver que obtivemos o mesmo resultado, mas o código usando pipe (e formatação do texto) ficou muito mais limpa e fácil de entender o que está sendo feito. Além disso, as operações são feitas em uma sequência compreensível, enquanto no modo anterior sempre tivemos que aninhar as operações, ou seja, fazê-las de “dentro pra fora”.
Vamos continuar nosso aprendizado das principais funções de dplyr, usando o pipe de agora em diante.
filter( )
A função filter, como o nome sugere, serve para filtrar linhas de acordo com algum critério. Vamos fazer alguns exemplos:
# Vamos filtrar apenas os alunos que tiveram nota1 maior ou igual a 8alunos |>filter(nota1 >=8)
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
Maria
Oliveira
19
Carla
Contabilidade
9.2
5.6
5.5
TRUE
MG
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
TRUE
SP
Ana
Almeida
22
Isabela
Direito
9.0
9.2
6.8
FALSE
MG
Juliana
Araujo
23
Karen
Engenharia
8.7
5.0
2.7
TRUE
RS
Sofia
Rocha
19
Olivia
Economia
9.5
1.3
1.3
TRUE
MG
Andre
Lima
25
Sabrina
Estatistica
8.2
4.1
7.1
FALSE
RS
# Filtrando alunos do curso de Economiaalunos |>filter(curso =="Economia")
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Fernanda
Ferreira
24
Gabriela
Economia
7.5
4.2
1.2
FALSE
PR
Pedro
Costa
27
Helena
Economia
6.5
1.6
3.1
TRUE
RJ
Sofia
Rocha
19
Olivia
Economia
9.5
1.3
1.3
TRUE
MG
# Podemos filtrar por várias condições# Vamos filtrar por nota1 >= 8 e nota2 menor que 5alunos |>filter(nota1 >=8, nota2 <5)
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
TRUE
SP
Sofia
Rocha
19
Olivia
Economia
9.5
1.3
1.3
TRUE
MG
Andre
Lima
25
Sabrina
Estatistica
8.2
4.1
7.1
FALSE
RS
# Ou combinar com o select e o arrange que já vimosalunos |>select(nome, nota1:nota3) |>filter(nota1 >=8, nota2 <5) |>arrange(nome)
nome
nota1
nota2
nota3
Ana
8.5
1.2
8.2
Andre
8.2
4.1
7.1
Lucas
8.0
3.3
3.9
Sofia
9.5
1.3
1.3
# também podemos já fazer uma conta na hora de filtrar# Vamos filtrar apenas alunos que tiveram a média maior que 7.5alunos |>filter((nota1 + nota2 + nota3)/3>7.5)
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
Ana
Almeida
22
Isabela
Direito
9.0
9.2
6.8
FALSE
MG
Marcos
Nascimento
26
Juliana
Medicina
5.8
10.0
9.1
TRUE
BA
Felipe
Costa
27
Vitoria
Estatistica
6.7
7.2
9.0
FALSE
RJ
mutate( )
Mutate é uma das funções mais importantes desse pacote. Com ele conseguimos criar novas colunas ou modificar as que já temos. Podemos usar diversas funções para criar essas colunas, fazendo do mutate uma função bem útil e versátil.
# vamos criar uma nova coluna que tenha a média das notas dos alunos# agora como quero salvar as mudanças, estou atribuindo ao objeto alunos# para que não fiquemos só com a visualização das mudançasalunos <- alunos |>mutate(media = (nota1 + nota2 + nota3)/3)alunos |>head()
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
media
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
5.966667
Paulo
Santos
25
Beatriz
Contabilidade
6.0
5.5
5.7
FALSE
RJ
5.733333
Maria
Oliveira
19
Carla
Contabilidade
9.2
5.6
5.5
TRUE
MG
6.766667
Joao
Souza
23
Daniela
Fisica
5.5
6.8
2.2
FALSE
BA
4.833333
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
TRUE
RS
6.200000
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
TRUE
SP
5.066667
# De fato a coluna foi criada. Agora vamos supor que o que fizemos antes# estava errado e que a média deveria ser uma média ponderada com pesos # 1, 2 e 3 para as notas, respectivamentealunos <- alunos |>mutate(media = (nota1 + nota2 *2+ nota3 *3)/6)alunos |>head()
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
media
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
5.916667
Paulo
Santos
25
Beatriz
Contabilidade
6.0
5.5
5.7
FALSE
RJ
5.683333
Maria
Oliveira
19
Carla
Contabilidade
9.2
5.6
5.5
TRUE
MG
6.150000
Joao
Souza
23
Daniela
Fisica
5.5
6.8
2.2
FALSE
BA
4.283333
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
TRUE
RS
5.533333
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
TRUE
SP
4.383333
# Podemos verificar que conseguimos alterar a coluna calculada# Agora vamos criar uma nova coluna que diz se os alunos foram aprovados# média 6alunos <- alunos |>mutate(aprovado =if_else(media >=6, T, F))alunos |>head()
nome
sobrenome
idade
nome_mae
curso
nota1
nota2
nota3
bolsista
uf
media
aprovado
Ana
Silva
22
Ana
Matematica
8.5
1.2
8.2
TRUE
SP
5.916667
FALSE
Paulo
Santos
25
Beatriz
Contabilidade
6.0
5.5
5.7
FALSE
RJ
5.683333
FALSE
Maria
Oliveira
19
Carla
Contabilidade
9.2
5.6
5.5
TRUE
MG
6.150000
TRUE
Joao
Souza
23
Daniela
Fisica
5.5
6.8
2.2
FALSE
BA
4.283333
FALSE
Carla
Lima
21
Eduarda
Letras
7.8
7.0
3.8
TRUE
RS
5.533333
FALSE
Lucas
Pereira
20
Fernanda
Quimica
8.0
3.3
3.9
TRUE
SP
4.383333
FALSE
group_by( ) e summarise( )
Essas duas funções geralmente são utilizadas em conjunto. Group by cria agrupamentos no dataframe. Após criarmos um agrupamento, todas as operações que fizermos serão feitas “dentro” desses agrupamentos. (Calma, vai ficar claro no exemplo). Já o summarise é utilizado para resumir o DataFrame. O summarise pode ser utilizado sozinho mas geralmente vamos trabalhar com dados agrupados para utilizar todo o potencial dessa funcionalidade. Vamos aos exemplos:
# Vamos supor que queremos a média das notas por curso. Como fariamos isso?# Temos que agrupar os alunos por curso e calcular as medias# Como só queremos a média por curso, as outras colunas não vão nos interessar# então já vamos selecionar apenas o que queremos# já vamos também order por média decrescente para descobrir quais cursos tem# a maior médiaalunos |>select(curso, nota1:nota3) |>group_by(curso) |>summarise(media =mean(c(nota1,nota2,nota3))) |>arrange(desc(media))
curso
media
Direito
8.333333
Medicina
8.300000
Psicologia
7.266667
Estatistica
7.050000
Contabilidade
6.011111
Matematica
5.966667
Arquitetura
5.866667
Engenharia
5.466667
Letras
5.122222
Quimica
5.066667
Fisica
4.833333
Economia
4.022222
Filosofia
3.966667
# Vamos agora contar quantos alunos temos por curso# Para isso usamos a função auxiliar do dplyr n( ). Essa função serve# Para contagens. Como só queremos contar, precisamos apenas de uma colunaalunos |>select(curso) |>group_by(curso) |>summarise(qtd =n()) |>arrange(desc(qtd))
curso
qtd
Contabilidade
3
Economia
3
Letras
3
Estatistica
2
Arquitetura
1
Direito
1
Engenharia
1
Filosofia
1
Fisica
1
Matematica
1
Medicina
1
Psicologia
1
Quimica
1
Juntando bases com left_join( )
A última funcionalidade que vamos aprender de dplyr no momento é a de unir bases. (Join para quem está familiarizado com SQL). Seria mais ou menos equivalente a fazer uma proc no Excel.
# Vamos criar um outro dataframe com a classificação dos cursos# e uma nota que seria como a nota CAPES do cursocursos <-c("Matematica", "Contabilidade", "Fisica", "Letras", "Quimica","Economia", "Direito", "Medicina", "Engenharia", "Psicologia","Arquitetura", "Filosofia", "Estatistica")# Classificação das áreasareas <-c("Exatas", # Matematica"Humanas", # Contabilidade"Exatas", # Fisica"Humanas", # Letras"Exatas", # Quimica"Humanas", # Economia"Humanas", # Direito"Biologicas", # Medicina"Exatas", # Engenharia"Biologicas", # Psicologia"Exatas", # Arquitetura"Humanas", # Filosofia"Exatas"# Estatistica)# Gerando notas aleatórias entre 1 e 5conceitos <-sample(1:5, length(cursos), replace =TRUE)# Criando o data framecursos <-data.frame(curso = cursos,conceito = conceitos,area = areas)
Agora vamos utilizar o left join para completar o data frame de alunos com as informações de cursos. Como não temos o mesmo número de linhas, não podemos utilizar o rbind que vimos anteriormente. Também queremos que o nome do curso seja uma “chave” para a busca das informações.
alunos <- alunos |>left_join(cursos, by ="curso")alunos |>head()