Curso Básico de Programação

Authors

Paulo José Rufino Rêgo

Marcelo Batalha Cunha



Módulo 1: Introdução à Programação

Introdução

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 pacotes
library(ggplot2)
library(stringr)
library(dplyr)
library(lubridate)
library(RColorBrewer)
library(unikn)
library(scales)

# Define as paletas de cores
paleta_sicoob <- c("#003641","#00AE9D","#49479D", "#7DB61C","#C9D200")

# Gera uma paleta com 10 cores a partir da paleta original
paleta_sicoob_expandida <- grDevices::colorRampPalette(paleta_sicoob)(10)

# Gera uma paleta com 6 cores a partir da paleta original
paleta_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á lido
caminho_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 arquivo
dados_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ódigo

1 + 2
3.5 + 0.0001

10 - 2
49.2 -  70.0345

2 * 3
4.5 * 2

5 / 2
476 / 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 ^ 10
4 ^ 0.5

4 %/% 3
10 %/% 3

10 %% 5
5 %% 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 1
TRUE == FALSE 
# Afirmação 2
FALSE == FALSE
# Afirmação 3
TRUE & FALSE
# Afirmação 4
T & T
# Afirmação 5
FALSE | FALSE

# Repare que utilizar Apenas T ou apenas F funciona como se utilizássemos
# a palavra inteira
# Afirmação 6
T | F
# Afirmação 7
!FALSE
# Afirmação 8
TRUE != FALSE
# Afirmação 9
1 < 2
# Afirmação 10
2 >= 2
# Afirmação 11
15 == 15.0
[1] "Afirmação 1 : FALSE"
[1] "Afirmação 2 : TRUE"
[1] "Afirmação 3 : FALSE"
[1] "Afirmação 4 : TRUE"
[1] "Afirmação 5 : FALSE"
[1] "Afirmação 6 : TRUE"
[1] "Afirmação 7 : TRUE"
[1] "Afirmação 8 : TRUE"
[1] "Afirmação 9 : TRUE"
[1] "Afirmação 10 : TRUE"

Variáveis (ou objetos)

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ável
empresa
[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 empresa

empresa <- "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.5

numero <- 25.5

# Agora que temos esse valor armazenado, podemos fazer operações com ele

numero * 3 + 40.5
[1] 117
# Note que se atribuirmos outro valor, o resultado da operação muda

numero <- 11.2
numero * 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úmero

contagem <- 1L

contagem + 2L
[1] 3
# Booleanos armazenam valores tipo Verdadeiro ou Falso
afirmacao <- TRUE & FALSE

afirmacao
[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 i

complicado <- 3 + 4i

complicado + 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 objeto

class(empresa)

class(numero)

class(contagem)

class(afirmacao)

class(complicado)
[1] "character"
[1] "numeric"
[1] "integer"
[1] "logical"
[1] "complex"

Possíveis problemas ao criar variáveis

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.

  1. 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 <- 15
Idade <- 13

idade == Idade
[1] FALSE
  1. 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.
  1. 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.6

inteiro <- 2L

class(numero)
class(inteiro)

inteiro <- numero + inteiro

class(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 utilizam

colegas <- c('Paulo', 'Marcelo', 'Nilo', 'Duda', 'Thiago')

# Podemos agora imprimir o vetor colegas para verificar como ele ficou

print(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 vetor

print(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 intervalo

print(colegas[c(2,3)])

print(colegas[1:4])

print(colegas[2:5])
[1] "Paulo"
[1] "Nilo"
[1] "Marcelo" "Nilo"   
[1] "Paulo"   "Marcelo" "Nilo"    "Duda"   
[1] "Marcelo" "Nilo"    "Duda"    "Thiago" 

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.

vetor_teste <- c('Paulo', 2, 2.5, 15178)

print(vetor_teste)

class(vetor_teste)
[1] "Paulo" "2"     "2.5"   "15178"
[1] "character"

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 1

exemplo <- seq(from = 1, to = 10, by = 1)

# Vamos criar um vetor concatenando 3 cópias do primeiro
exemplo2 <- 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)


# Soma
sum(exemplo)

# Média
mean(exemplo)

# Mediana
median(exemplo)

# Mìnimo
min(exemplo)

# Máximo
max(exemplo)

# Variância
var(exemplo)

# Desvio Padrão
sd(exemplo)

# Só conferindo que de fato o desvio padrão é a raiz quadrada da variância
var(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 testado

c(1,2,3,100) %in% exemplo

# Também podemos fazer o mesmo teste apenas com um valor

4 %in% exemplo

123 %in% exemplo
 [1]  1  2  3  4  5  6  7  8  9 10
 [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5
[26]  6  7  8  9 10
[1] 10
[1] 30
 [1]  1  2  3  4  5  6  7  8  9 10
[1] 55
[1] 5.5
[1] 5.5
[1] 1
[1] 10
[1] 9.166667
[1] 3.02765
[1] 3.02765
[1]  TRUE  TRUE  TRUE FALSE
[1] TRUE
[1] FALSE
vetor_teste <- c('Paulo', 2, 2.5, 15178)

print(vetor_teste)

class(vetor_teste)
[1] "Paulo" "2"     "2.5"   "15178"
[1] "character"

Operações com vetores

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ógicos

exemplo_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ção

exemplo + exemplo

# podemos também somar ou subtrair um valor a todos os elementos do vetor

exemplo + 3
exemplo - 1

# Multiplicar um vetor pelo outro resulta na multiplicação vetorial
# No caso a seguir seria como elevar cada elemento ao quadrado

exemplo * exemplo

# Também podemos multiplicar ou dividir por constantes

exemplo / 2

exemplo * 3

# POdemos realizar todas as operações lógicas que conhecemos com o vetor de 
# valores lógicos

exemplo_logico & T

exemplo_logico | T
 [1]  2  4  6  8 10 12 14 16 18 20
 [1]  4  5  6  7  8  9 10 11 12 13
 [1] 0 1 2 3 4 5 6 7 8 9
 [1]   1   4   9  16  25  36  49  64  81 100
 [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
 [1]  3  6  9 12 15 18 21 24 27 30
[1]  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Agora uma pergunta: o que acontece se aplicarmos alguma condição a um vetor numérico? Qual a classe do vetor resultante?

# Criando vetores para tirar essa dúvida

teste1 <- exemplo > 4

teste2 <- exemplo <= 3

Ao aplicar uma condição a um vetor númerico, obtemos como resultado um vetor lógico. Isso vai ser bastante útil no futuro próximo

print(teste1)
 [1] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
print(teste2)
 [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

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ógicos
sum(exemplo_logico)
[1] 3
# Calculando a média de valores lógicos
mean(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 lista

funcionario <- list("Paulo", "Analista", 34, 15)

# Podemos acessar os itens pelo índice, como fizemos anteriormente nos vetores
funcionario[1]
funcionario[3]

# Ao invés de utilizar só os índices podemos também nomear os elementos

cadastro <- 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 resultado

cadastro[1]
cadastro$nome

cadastro[3]
cadastro$idade
[[1]]
[1] "Paulo"

[[1]]
[1] 34

$nome
[1] "Paulo"

[1] "Paulo"
$idade
[1] 34

[1] 34

Matrizes

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) queremos

matriz <- matrix(1:12, nrow = 4, ncol = 3)

# Mostrando como fica a matriz
print(matriz)

# Acessando elementos específicos

# Aqui queremos acessar o elemento da linha 1 e coluna 2
matriz[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 colunas

matriz[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 colunas

matriz[ , c(2,3)]

# E aqui, todos os elementos da primeira linha
matriz[1, ]
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12
[1] 5
     [,1] [,2]
[1,]    5    9
[2,]    7   11
     [,1] [,2]
[1,]    5    9
[2,]    6   10
[3,]    7   11
[4,]    8   12
[1] 1 5 9

DataFrames

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 diante

df <- 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 criar
print(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ções

nrow(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 acima

df$nomes

df[["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 DataFrame

subset(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 bolsistas

df$bolsista <- c(T,F,F,T,F)

# Também podemos fazer isso para substituir ou alterar uma coluna

df[["nomes"]] <- c("Paulo", "Pedro", "Mariana","Marcus","Luiza")


# Vamos visualizar como ficou o DataFrame com as alterações

print(df)
[1] "Paulo"   "Pedro"   "Mariana" "Marcus"  "Clara"  
[1] "Paulo"   "Pedro"   "Mariana" "Marcus"  "Clara"  
[1] "Paulo"   "Pedro"   "Mariana" "Marcus"  "Clara"  
nomes
Paulo
Pedro
Mariana
Marcus
Clara
    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 linha
df[1, ]

# Selecionando a primeira e a quarta linhas
df[c(1,4),]

# Selecionando as linhas de 1 a 3

df[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 M

df[df$genero == "M",]

# Agora, supondo uma média 6, vamos selecionar apenas os alunos aprovados
# e salvá-los em outro DataFrame

dfaprovados <- df[df$notas >= 6, ]

print(dfaprovados)

# Agora vamos separar também os reprovados em outro DataFrame

dfreprovados <- 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 7

df[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ógicos

df[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 unir
df2 <- rbind(dfaprovados,dfreprovados)

# Verificando que reconstituimos o DataFrame original
print(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 coluna
df2 <- 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

  1. Crie um vetor chamado exercicio1 contendo a sequência de números pares de 2 a 20

  2. Adicione 3 a todos os elementos desse vetor

  3. Multiplique esse vetor por 5

  4. Imprima o primeiro elemento desse vetor

  5. Imprima os últimos 3 elementos desse vetor

  6. 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

  1. 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.
  1. Quais os nomes dos alunos nas linhas 3 e 4 do DataFrame? Responda com um vetor para que a resposta seja avaliada corretamente.
  1. Qual a maior nota entre os alunos?
  1. Quantos alunos têm 25 anos ou mais?
    1. Dica! As função length, sum ou nrow podem ser úteis. Há como resolver esse exercício utilizando qualquer uma dessas
  1. Liste os alunos que são bolsistas e tiveram nota abaixo da média.
    1. 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
  1. Considere que a média para aprovação nessa faculdade é 6.5. Crie um novo DataFrame apenas com os alunos aprovados
  1. 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
  1. 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.
novo_aluno <- list(
  nome = "Jonas",
  idade = 19,
  curso = "Historia",
  nota = 7.8,
  bolsista = FALSE,
  uf = "ES"
)
  1. 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
}else if(condicao2) {
  código a ser executado caso a condição 2 seja verdadeira
}else if(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 simples
if(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ção

if(condicao){
  código a ser executado caso a condição 1 seja verdadeira
}else if(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 alunos

notas <- 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ão

resultado <- ifelse(notas >= 5, "Aluno Aprovado!", "Aluno Reprovado =(")

print(resultado)
 [1] "Aluno Reprovado =(" "Aluno Aprovado!"    "Aluno Aprovado!"   
 [4] "Aluno Aprovado!"    "Aluno Reprovado =(" "Aluno Reprovado =("
 [7] "Aluno Aprovado!"    "Aluno Reprovado =(" "Aluno Aprovado!"   
[10] "Aluno Aprovado!"    "Aluno Reprovado =("

while

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 in 1:6){
  
  print(paste("Estou na posição ", i))
  
}

# Os vetores utilizados no laço não precisam ser numéricos

nomes <- 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 8

soma <- T

while(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 inicial
  if(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 pares

for(i in 1: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ção
  
  return( )
}

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ção
e_par(246)

e_par(15)


# Também podemos guardar os resultados da nossa função
# em um objeto

a <- 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:

  1. 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).

  1. 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
  1. 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

  1. 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.

# Definindo o dataframe

alunos <- data.frame(
  nome = c("Ana", "Paulo", "Maria", "Joao", "Carla", 
           "Lucas", "Fernanda", "Pedro", "Ana", "Marcos",
           "Juliana", "Thiago", "Clara", "Roberto", "Sofia",
           "Andre", "Camila", "Andre", "Isabela", "Felipe"),
  sobrenome = c(
  "Silva", "Santos", "Oliveira", "Souza", "Lima",
  "Pereira", "Ferreira", "Costa", "Almeida", "Nascimento",
  "Araujo", "Carvalho", "Gomes", "Martins", "Rocha",
  "Silva", "Souza", "Lima", "Pereira", "Costa"
  ),
  
  idade = c(22, 25, 19, 23, 21, 
            20, 24, 27, 22, 26,
            23, 28, 21, 30, 19,
            24, 22, 25, 20, 27),
  nome_mae = c(
  "Ana", "Beatriz", "Carla", "Daniela", "Eduarda",
  "Fernanda", "Gabriela", "Helena", "Isabela", "Juliana",
  "Karen", "Larissa", "Mariana", "Natalia", "Olivia",
  "Patricia", "Rafaela", "Sabrina", "Tatiane", "Vitoria"
),
  
  curso = c("Matematica", "Contabilidade", "Contabilidade", "Fisica", "Letras", 
            "Quimica", "Economia", "Economia", "Direito", "Medicina",
            "Engenharia", "Psicologia", "Arquitetura", "Filosofia", "Economia",
            "Contabilidade", "Letras", "Estatistica", "Letras", "Estatistica"),
  nota1 = c(8.5, 6.0, 9.2, 5.5, 7.8, 
           8.0, 7.5, 6.5, 9.0, 5.8,
           8.7, 7.2, 6.8, 5.9, 9.5,
           7.0, 6.3, 8.2, 7.9, 6.7),
  nota2 = c(1.2, 5.5, 5.6, 6.8, 7.0,
            3.3, 4.2, 1.6, 9.2, 10.0,
            5.0, 7.5, 7.3, 3.6, 1.3,  
            4.7, 3.0, 4.1, 4.9, 7.2),
  nota3 = c(8.2, 5.7, 5.5, 2.2, 3.8,
            3.9, 1.2, 3.1, 6.8, 9.1,
            2.7, 7.1, 3.5, 2.4, 1.3,
            4.9, 4.1, 7.1, 1.3, 9.0),
  bolsista = c(TRUE, FALSE, TRUE, FALSE, TRUE, 
               TRUE, FALSE, TRUE, FALSE, TRUE,
               TRUE, FALSE, TRUE, FALSE, TRUE,
               FALSE, TRUE, FALSE, TRUE, FALSE),
  uf = c("SP", "RJ", "MG", "BA", "RS", 
             "SP", "PR", "RJ", "MG", "BA",
             "RS", "SP", "PR", "RJ", "MG",
             "BA", "SP", "RS", "PR", "RJ")
)

select ()

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 seguinte

head(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 bolsista
head(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é nota1
head(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 consecutivas

head(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
# ou

head(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 nomes

head(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 sobrenome

head(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 nome

head(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 idade

head(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 diferentes
head(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 decrescente

head(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 pipe

alunos |> 
  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 8

alunos |>
  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 Economia

alunos |>
  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 5
  
alunos |>
  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á vimos

alunos |>
  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.5

alunos |>
  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ças

alunos <- 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, respectivamente

alunos <- 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 6

alunos <- 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édia

alunos |>
  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 coluna

alunos |>
  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 curso

cursos <- c(
  "Matematica", "Contabilidade", "Fisica", "Letras", "Quimica",
  "Economia", "Direito", "Medicina", "Engenharia", "Psicologia",
  "Arquitetura", "Filosofia", "Estatistica"
)

# Classificação das áreas
areas <- 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 5
conceitos <- sample(1:5, length(cursos), replace = TRUE)

# Criando o data frame
cursos <- 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()
nome sobrenome idade nome_mae curso nota1 nota2 nota3 bolsista uf media aprovado conceito area
Ana Silva 22 Ana Matematica 8.5 1.2 8.2 TRUE SP 5.916667 FALSE 1 Exatas
Paulo Santos 25 Beatriz Contabilidade 6.0 5.5 5.7 FALSE RJ 5.683333 FALSE 1 Humanas
Maria Oliveira 19 Carla Contabilidade 9.2 5.6 5.5 TRUE MG 6.150000 TRUE 1 Humanas
Joao Souza 23 Daniela Fisica 5.5 6.8 2.2 FALSE BA 4.283333 FALSE 1 Exatas
Carla Lima 21 Eduarda Letras 7.8 7.0 3.8 TRUE RS 5.533333 FALSE 4 Humanas
Lucas Pereira 20 Fernanda Quimica 8.0 3.3 3.9 TRUE SP 4.383333 FALSE 5 Exatas