EAE1106 - Métodos Computacionais para Economia
Faculdade de Economia, Administração, Contabilidade e Atuária
Universidade de São Paulo

Prof. Arthur Viaro
1º semestre de 2026


Aula 24 - Introdução ao R: Sintaxe, Objetos e Comparação com Python


Por que aprender R?

  • R é uma linguagem criada especificamente para análise estatística e computação científica, amplamente utilizada em:

    • Econometria e estatística
    • Ciência de dados e aprendizado de máquina
    • Pesquisa acadêmica
    • Análise financeira e atuarial
  • O ecossistema do Tidyverse torna R extremamente poderoso para manipulação e visualização de dados

  • Junto com Python, R é uma das duas linguagens dominantes em ciência de dados — muitas equipes usam ambas

  • R possui uma comunidade acadêmica enorme, com pacotes para praticamente qualquer método estatístico


Instalação e Configuração

Para programar em R, você precisará instalar a linguagem e um ambiente de desenvolvimento (IDE). As opções mais populares são:

  1. R (a linguagem em si): https://cloud.r-project.org/
  2. RStudio (IDE tradicional para R): https://posit.co/download/rstudio-desktop/
  3. Positron (IDE moderna baseada no VSCode): https://positron.posit.co/download.html

O RStudio foi por muitos anos o ambiente padrão para desenvolvimento em R e continua sendo amplamente utilizado. Entretanto, o Visual Studio Code (VSCode) oferece maior flexibilidade, suporte a múltiplas linguagens e um amplo ecossistema de extensões.

Outra alternativa interessante é o Positron, desenvolvido pela mesma empresa responsável pelo RStudio (Posit). O Positron combina a experiência tradicional do RStudio com a flexibilidade e modernidade do VSCode, sendo uma excelente opção para novos usuários.

Instalando R no Anaconda para Uso com Jupyter Notebook

Se você utiliza Anaconda, é possível instalar o R e integrá-lo ao Jupyter Notebook sem precisar instalar o R separadamente. Essa abordagem facilita o gerenciamento de pacotes e ambientes de desenvolvimento.

Para facilitar o processo, utilizaremos o canal conda-forge, que mantém as versões do R mais atualizadas. O comando abaixo instalará o R base, o kernel do Jupyter e as principais bibliotecas de análise de dados (como ggplot2 e dplyr) de uma só vez.

  1. Abra o Anaconda Prompt (no Windows) ou o Terminal (no Linux/Mac).
  2. Copie, cole o comando abaixo e pressione Enter:
conda install -c conda-forge r-essentials r-irkernel --yes

O parâmetro --yes no final serve para aceitar automaticamente a instalação de todas as dependências, tornando o processo mais direto. A instalação pode levar alguns minutos dependendo da velocidade da internet.

Com a instalação concluída, o R já estará integrado ao seu ambiente padrão. Ao criar um novo notebook, a opção R estará disponível na lista de kernels.

Configurando o VSCode para R

  1. Instalar o R e o VSCode

Primeiro, instale o R e o VSCode em seu computador:

  1. Instalar a extensão R para VSCode

    • Acesse a aba de Extensões no VSCode
    • Pesquise por “R” e instale a extensão desenvolvida por Yuki Ueda (REditorSupport)

Essa extensão fornece recursos como destaque de sintaxe, execução de código e integração com o terminal R.

  1. Instalar o pacote languageserver

O pacote languageserver habilita funcionalidades como autocompletar, documentação automática e verificação de código.

  • Abra a Central de Comando (Ctrl + Shift + P).
  • Execute o comando “R: Create R Terminal”.
  • No terminal R, execute: install.packages("languageserver")
  1. Configurar o Radian (Opcional, mas Recomendado)

O Radian é um terminal interativo para R que oferece uma experiência mais moderna, incluindo autocompletar, destaque de sintaxe e melhor navegação no histórico de comandos.

  • Se você utiliza o Anaconda ou Miniconda, instale o Radian com: conda install -c conda-forge radian
  • Após a instalação, localize o executável executando no Prompt de Comando: where radian
  • Um caminho típico é C:\Users\SeuUsuario\anaconda3\Scripts\radian.exe

Agora, vamos configurar o VSCode para utilizar o Radian:

  • Abra a Central de Comando (Ctrl + Shift + P).
  • Selecione “Preferences: Open User Settings (JSON)”.
  • Adicione as seguintes configurações ao arquivo settings.json, ajustando os caminhos para sua instalação:
{
    "r.rterm.windows": "C:\\Users\\SeuUsuario\\anaconda3\\Scripts\\radian.exe",
    "r.rpath.windows": "C:\\Program Files\\R\\R-4.5.0\\bin\\R.exe",
    "r.bracketedPaste": true
}

Importante: em caminhos do Windows, utilize barras invertidas duplas (\\) dentro do arquivo JSON.

  1. Configurar atalhos de teclado

Alguns atalhos tornam a escrita de código em R mais rápida e confortável.

  • Abra a Central de Comando (Ctrl + Shift + P).
  • Procure por “Preferences: Open Keyboard Shortcuts (JSON)”.
  • Adicione as seguintes configurações ao arquivo aberto:
[
    {
        "key": "alt+-",
        "command": "type",
        "args": { "text": " <- " },
        "when": "editorTextFocus && editorLangId == r"
    },
    {
        "key": "ctrl+shift+m",
        "command": "type",
        "args": { "text": " %>% " },
        "when": "editorTextFocus && editorLangId == r"
    }
]

Os atalhos configurados são semelhantes aos utilizados em ambientes como RStudio e Jupyter Notebook e permitem:

  • Alt + -: inserir rapidamente o operador de atribuição (<-);
  • Ctrl + Shift + M: inserir o operador pipe (|>).

Após salvar as configurações, reinicie o VSCode para que as alterações sejam aplicadas.

Instalando e Carregando Pacotes

Em R, bibliotecas são chamadas de pacotes. Para instalar um pacote, utilize a função install.packages():

# Instalar o Tidyverse (conjunto de pacotes essenciais)
install.packages("tidyverse")

Após a instalação, o pacote pode ser carregado com a função library():

library(tidyverse)

Importante: install.packages() precisa ser executado apenas uma vez em cada computador. Já library() deve ser executado sempre que uma nova sessão do R for iniciada.


Sintaxe Básica

Operações Aritméticas

R funciona como uma calculadora poderosa:

# Operações básicas
1 + 2
## [1] 3
10 - 3
## [1] 7
4 * 5
## [1] 20
10 / 3
## [1] 3.333333
# Potenciação
2^10
## [1] 1024
# Resto da divisão (em Python: 10 % 3)
10 %% 3
## [1] 1
# Divisão inteira (em Python: 10 // 3)
10 %/% 3
## [1] 3

Para funções de cálculo matemático e estatístico básico:

# Raiz quadrada
sqrt(16)
## [1] 4
# Valor absoluto
abs(-42)
## [1] 42
# Logaritmo natural
log(100)
## [1] 4.60517
# Logaritmo base 10
log10(100)
## [1] 2
# Logaritmo base 2
log2(100)
## [1] 6.643856
# Logaritmo base 5
log(100, base = 5)
## [1] 2.861353
# Número de Euler (e)
exp(1)
## [1] 2.718282
# Arredondamento
round(3.14159, 2)
## [1] 3.14

Variáveis e Atribuição

Em Python, o operador de atribuição é =. Já em R, o operador de atribuição padrão é <- (embora = também funcione):

# Atribuição padrão R (<-)
x <- 42
y <- 3.14
nome <- "Economia"
# Verificar o tipo de um objeto
class(x)
## [1] "numeric"
class(y)
## [1] "numeric"
class(nome)
## [1] "character"

Dica: No RStudio, use Alt + - (Windows/Linux) ou Option + - (Mac) para digitar <- rapidamente.


Tipos de Dados

Numérico e Inteiro

R possui diferentes tipos de dados para representar valores numéricos. Por padrão, números são armazenados como valores numéricos de ponto flutuante (double precision), mesmo quando não possuem casas decimais.

Nota: Numeric é um termo mais amplo que engloba tanto números decimais (double) quanto inteiros (integer), enquanto double se refere estritamente a números de ponto flutuante de dupla precisão.

# Valores numéricos (double)
x <- 3.14
y <- 10

class(x)
## [1] "numeric"
typeof(x)
## [1] "double"
class(y)
## [1] "numeric"
typeof(y)
## [1] "double"

Para criar um valor explicitamente inteiro, utiliza-se o sufixo L:

# Valor inteiro
n <- 42L

class(n)
## [1] "integer"
typeof(n)
## [1] "integer"
is.integer(n)
## [1] TRUE

Embora integer e double sejam armazenados de formas diferentes, ambos representam valores numéricos. Por isso, a função is.numeric() retorna TRUE para os dois casos.

is.numeric(3.14)
## [1] TRUE
is.double(3.14)
## [1] TRUE
is.numeric(42L)
## [1] TRUE
is.integer(42L)
## [1] TRUE

Conversão de Tipos

A conversão entre tipos pode ser realizada com funções da família as.*().

# Double para inteiro
as.integer(3.7)
## [1] 3
# Inteiro para double
as.double(5L)
## [1] 5

Importante: as.integer() remove a parte decimal do número, ou seja, realiza um truncamento e não um arredondamento.

as.integer(3.9)
## [1] 3
as.integer(-3.9)
## [1] -3

Para arredondar valores, utilize funções como round(), floor() ou ceiling():

round(3.9)
## [1] 4
floor(3.9)
## [1] 3
ceiling(3.1)
## [1] 4

Character (Texto / String)

No R, o tipo de dado para texto se chama character. Aceita aspas simples ou duplas. É equivalente à classe str do Python.

curso <- "Economia"
universidade <- "USP"

# Converte número para string
as.character(100)
## [1] "100"
# Concatenação de textos com paste() e paste0()
paste(curso, "na", universidade) # Adiciona espaço por padrão
## [1] "Economia na USP"
paste0(curso, "@", universidade) # Concatenação sem espaços
## [1] "Economia@USP"

Manipulação de Strings

A tabela abaixo resume o equivalente das operações de string para quem vem do Python:

Operação R Python
Comprimento nchar(x) len(x)
Fatiamento substr(x, start, stop) x[start:stop]
Caixa Alta toupper(x) x.upper()
Caixa Baixa tolower(x) x.lower()
Limpar espaços trimws(x) x.strip()
Substituição gsub(pattern, replacement, x) x.replace(pattern, replacement)
nchar("FEA-USP")
## [1] 7
toupper("economia")
## [1] "ECONOMIA"
tolower("ECONOMIA")
## [1] "economia"
trimws("  texto com espaços  ")
## [1] "texto com espaços"

Fatiamento e Substituição

Nota de Sintaxe: O R utiliza índices base 1 (o primeiro caractere está na posição 1) e o intervalo final é inclusivo.

# Substring (em Python: texto[0:3])
substr("Economia", 1, 4)
## [1] "Econ"
# Substituição de padrões (em Python: texto.replace("a", "@"))
gsub("a", "@", "banana") # Substitui todas as ocorrências
## [1] "b@n@n@"
sub("a", "@", "banana") # Substitui apenas a primeira
## [1] "b@nana"

Formatação de Texto

Para construir strings formatadas (similar às f-strings do Python), utilizamos a função sprintf() baseada na sintaxe C.

A função permite inserir valores de variáveis dentro de um texto usando marcadores de posição (placebholders) como %s para strings, %d para inteiros e %.2f para números de ponto flutuante com 2 casas decimais.

nome <- "Murilo"
nota <- 9.5
sprintf("O(a) aluno(a) %s obteve nota %.2f", nome, nota)
## [1] "O(a) aluno(a) Murilo obteve nota 9.50"

Booleanos

Declarados sempre em caixa alta: TRUE (ou T) e FALSE (ou F).

# Booleanos em R: TRUE e FALSE (em Python: True e False)
verdadeiro <- TRUE
falso <- FALSE

class(verdadeiro)
## [1] "logical"
# Operadores de comparação
5 > 3
## [1] TRUE
5 < 3
## [1] FALSE
5 == 5
## [1] TRUE
5 != 3
## [1] TRUE
5 >= 5
## [1] TRUE
5 <= 4
## [1] FALSE

Operadores Lógicos

Em Python, os operadores lógicos são and (E), or (OU) e not (NÃO). Em R, utilizam-se &, | e ! para operações elemento a elemento em vetores.

x <- c(10, 20, 30, 40)
y <- c(15, 25, 35, 45)

# & (E - elemento a elemento)
x > 5 & y < 30
## [1]  TRUE  TRUE FALSE FALSE
# | (OU - elemento a elemento)
x > 25 | y < 30
## [1] TRUE TRUE TRUE TRUE
# ! (NÃO - elemento a elemento)
!(x > 0)
## [1] FALSE FALSE FALSE FALSE

Os operadores && e || realizam avaliação com curto-circuito, ou sejam comparam apenas o primeiro elemento de cada vetor ou expressão e param assim que o resultado é conhecido.

x <- 10
y <- 5

# && (E - Curto-circuito)
(x > 5) && (y < 10)
## [1] TRUE
(x < 5) && (y < 10) # não avalia a segunda parte, já que a primeira é FALSE
## [1] FALSE
# || (OU - Curto-circuito)
(x < 5) || (y < 10)
## [1] TRUE
(x > 5) || (y < 0) # não avalia a segunda parte, já que a primeira é TRUE
## [1] TRUE

Valores Especiais

O R possui alguns valores reservados para representar situações específicas. NA indica um valor ausente (missing value), NULL representa um objeto nulo ou vazio, Inf e -Inf representam infinito positivo e negativo, respectivamente, e NaN (Not a Number) indica um resultado numérico indefinido ou inválido.

Para verificar esses valores, podem ser utilizadas funções como is.na(), is.null() e is.infinite().

# Valor ausente
x <- c(10, 20, NA, 40)
x
## [1] 10 20 NA 40
# Objeto nulo
y <- NULL
y
## NULL
# Operações que geram infinito
1 / 0
## [1] Inf
-1 / 0
## [1] -Inf
# Operação indefinida (NaN)
0 / 0
## [1] NaN
# Verificações
is.na(x[3])
## [1] TRUE
is.null(y)
## [1] TRUE
is.infinite(1 / 0)
## [1] TRUE
is.nan(0 / 0)
## [1] TRUE

Estruturas de Dados

Vetores

O vetor é a estrutura de dados mais importante do R e a base para praticamente todas as operações da linguagem. Ele é semelhante a uma lista unidimensional ou array em Python, mas com uma diferença importante: todos os elementos de um vetor devem possuir o mesmo tipo de dado (numérico, texto, lógico etc.).

Vetores são criados com a função c() (combine), que concatena valores em uma única estrutura:

notas <- c(8.5, 9.0, 7.5, 10.0, 8.0)
alunos <- c("Ana", "Bruno", "Carlos", "Diana", "Eduardo")

notas
## [1]  8.5  9.0  7.5 10.0  8.0
alunos
## [1] "Ana"     "Bruno"   "Carlos"  "Diana"   "Eduardo"

É possível criar sequências de números usando o operador : ou a função seq(), e repetir valores com rep():

# De 1 a 10
1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
# De 0 a 1, de 0.2 em 0.2
seq(0, 1, 0.2)
## [1] 0.0 0.2 0.4 0.6 0.8 1.0
# 5 valores entre 1 e 100
seq(1, 100, length.out = 5)
## [1]   1.00  25.75  50.50  75.25 100.00
# 0 repetido 5 vezes
rep(0, 5)
## [1] 0 0 0 0 0
# Sequência repetida
rep(c(1, 2), 3)
## [1] 1 2 1 2 1 2

Estatísticas e Operações com Vetores

Quando um vetor contém valores numéricos, o R disponibiliza diversas funções para realizar cálculos estatísticos de forma simples e eficiente, como tamanho, soma, média, desvio padrão, valor mínimo e valor máximo.

length(notas) # Tamanho (como len() em Python)
## [1] 5
sum(notas) # Soma
## [1] 43
mean(notas) # Média
## [1] 8.6
sd(notas) # Desvio padrão
## [1] 0.9617692
min(notas) # Mínimo
## [1] 7.5
max(notas) # Máximo
## [1] 10

Operações Vetorizadas

Uma das principais características do R é a vetorização. Operações matemáticas e funções são aplicadas automaticamente a todos os elementos de um vetor, sem a necessidade de laços de repetição explícitos.

Essa abordagem torna o código mais simples, legível e eficiente (em Python, para obter o mesmo resultado, seria necessário usar a biblioteca NumPy ou uma compreensão de lista).

notas * 10 # Multiplica cada elemento por 10
## [1]  85  90  75 100  80
notas + 0.5 # Adiciona 0.5 a cada nota
## [1]  9.0  9.5  8.0 10.5  8.5
sqrt(notas) # Raiz quadrada de cada elemento
## [1] 2.915476 3.000000 2.738613 3.162278 2.828427

Indexação

Os elementos de um vetor podem ser acessados por posição. Diferentemente de Python, a indexação em R começa em 1, e não em 0. Também é possível selecionar múltiplos elementos, intervalos de posições ou excluir elementos específicos.

# Primeiro elemento (em Python: notas[0])
notas[1]
## [1] 8.5
# Terceiro elemento
notas[3]
## [1] 7.5
# Elementos 1, 3 e 5
notas[c(1, 3, 5)]
## [1] 8.5 7.5 8.0
# Todos exceto o primeiro
notas[-1]
## [1]  9.0  7.5 10.0  8.0
# Do segundo ao quarto
notas[2:4]
## [1]  9.0  7.5 10.0

A indexação lógica é um dos recursos mais poderosos do R. Ela permite filtrar elementos com base em condições, retornando apenas aqueles que satisfazem o critério especificado.

# Equivalente em Python: [n for n in notas if n >= 9]
# Notas maiores ou iguais a 9
notas[notas >= 9]
## [1]  9 10
# Alunos com nota >= 9
alunos[notas >= 9]
## [1] "Bruno" "Diana"

Nomeação de Elementos de um Vetor

Além da indexação por posição, os elementos de um vetor podem receber nomes. Isso facilita a identificação dos dados e permite acessar valores diretamente pelo nome associado a cada elemento.

# Nomear elementos de um vetor
names(notas) <- alunos
notas
##     Ana   Bruno  Carlos   Diana Eduardo 
##     8.5     9.0     7.5    10.0     8.0
# Acessar por nome
notas["Ana"]
## Ana 
## 8.5

Matrizes

Uma matriz é uma estrutura bidimensional composta por linhas e colunas. Em R, todos os elementos de uma matriz devem ser do mesmo tipo de dado, assim como ocorre com os vetores. Pode-se pensar em uma matriz como um conjunto de vetores de mesmo comprimento organizados em forma de tabela.

Matrizes são criadas com a função matrix(), na qual especificamos os dados e suas dimensões:

# Criar uma matriz com 2 linhas e 3 colunas
A <- matrix(1:6, nrow = 2, ncol = 3)
A
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

O padrão é preencher por colunas. Use byrow = TRUE para preencher por linhas.

A <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE)
A
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6

Também é possível construir matrizes combinando vetores existentes.

  • cbind(): Combina vetores como colunas.
  • rbind(): Combina vetores como linhas.
v1 <- c(1, 2, 3)
v2 <- c(4, 5, 6)

# União por colunas
mat_col <- cbind(v1, v2)
mat_col
##      v1 v2
## [1,]  1  4
## [2,]  2  5
## [3,]  3  6
# União por linhas
mat_row <- rbind(v1, v2)
mat_row
##    [,1] [,2] [,3]
## v1    1    2    3
## v2    4    5    6

Os elementos de uma matriz são acessados utilizando a sintaxe matriz[linha, coluna]:

# Elemento na linha 2, coluna 3
A[2, 3]
## [1] 6

Também é possível selecionar linhas ou colunas inteiras:

# Segunda linha
A[2, ]
## [1] 4 5 6
# Terceira coluna
A[, 3]
## [1] 3 6

Além disso, podemos selecionar múltiplas linhas ou colunas simultaneamente:

# Linhas 1 e 2
A[c(1, 2), ]
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
# Colunas 1 e 3
A[, c(1, 3)]
##      [,1] [,2]
## [1,]    1    3
## [2,]    4    6

Atributos de uma Matriz

As matrizes possuem diversos atributos úteis para descrever sua estrutura:

  • nrow(): retorna o número de linhas;
  • ncol(): retorna o número de colunas;
  • dim(): retorna as dimensões da matriz (linhas e colunas);
  • rownames(): define ou consulta os nomes das linhas;
  • colnames(): define ou consulta os nomes das colunas.
dim(A)
## [1] 2 3
nrow(A)
## [1] 2
ncol(A)
## [1] 3
rownames(A) <- c("Linha1", "Linha2")
colnames(A) <- c("Coluna1", "Coluna2", "Coluna3")
A
##        Coluna1 Coluna2 Coluna3
## Linha1       1       2       3
## Linha2       4       5       6

A nomeação de linhas e colunas torna a matriz mais legível e facilita a identificação dos dados, especialmente em aplicações estatísticas e análise de dados.

Operações com Matrizes

Também podemos executar operações com matrizes, como multiplicação elemento a elemento, produto matricial, transposição e cálculo de determinante:

A <- matrix(1:9, nrow = 3, ncol = 3)
B <- matrix(2:10, nrow = 3, ncol = 3)

# produto dos elementos de matrizes
A * B
##      [,1] [,2] [,3]
## [1,]    2   20   56
## [2,]    6   30   72
## [3,]   12   42   90
# subtracao de valores de matrizes
A[3, 2] - B[3, 1]
## [1] 2
# alterando elemento
A[1, 2] <- 11

# produto matricial
A %*% B
##      [,1] [,2] [,3]
## [1,]   63  120  177
## [2,]   51   96  141
## [3,]   60  114  168
# matriz transposta
t(A)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]   11    5    6
## [3,]    7    8    9
# determinante da matriz
det(A)
## [1] 42

Fatores

Fatores (factors) são estruturas utilizadas para representar variáveis categóricas. Em vez de armazenar apenas os valores observados, um fator também mantém informações sobre todas as categorias possíveis (chamadas de níveis). Eles são amplamente utilizados em análise estatística, modelagem e visualização de dados.

Um fator pode ser visto como o equivalente às variáveis categóricas (Categorical) do pandas em Python.

# Criar um fator
regiao <- c("Sul", "Norte", "Sudeste", "Norte", "Sul", "Centro-Oeste")
regiao_fator <- factor(regiao)
regiao_fator
## [1] Sul          Norte        Sudeste      Norte        Sul         
## [6] Centro-Oeste
## Levels: Centro-Oeste Norte Sudeste Sul
# Níveis (categorias únicas)
levels(regiao_fator)
## [1] "Centro-Oeste" "Norte"        "Sudeste"      "Sul"
# Número de níveis
nlevels(regiao_fator)
## [1] 4
# Frequência de cada categoria
table(regiao_fator)
## regiao_fator
## Centro-Oeste        Norte      Sudeste          Sul 
##            1            2            1            2

Fatores Ordenados

Algumas variáveis categóricas possuem uma ordem natural entre suas categorias, como níveis de escolaridade, satisfação ou classificação de risco. Nesses casos, podemos criar um fator ordenado (ordered factor).

# Fator ordenado (ordinal)
escolaridade <- c("Médio", "Superior", "Fundamental", "Superior", "Médio")

escolaridade_ord <- factor(escolaridade,
    levels = c("Fundamental", "Médio", "Superior"),
    ordered = TRUE
)

escolaridade_ord
## [1] Médio       Superior    Fundamental Superior    Médio      
## Levels: Fundamental < Médio < Superior

Como existe uma ordem definida entre os níveis, comparações passam a fazer sentido:

escolaridade_ord[1] < escolaridade_ord[2] # TRUE, pois Médio < Superior
## [1] TRUE

Listas

Listas são estruturas de dados flexíveis que podem armazenar elementos de diferentes tipos e tamanhos em um único objeto.

Diferentemente dos vetores, que exigem elementos do mesmo tipo, uma lista pode conter números, textos, vetores, matrizes, data frames e até mesmo outras listas.

# Criando uma lista simples
minha_lista <- list("R", 2026, TRUE, c(1, 2, 3))
minha_lista
## [[1]]
## [1] "R"
## 
## [[2]]
## [1] 2026
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] 1 2 3

Os elementos de uma lista podem ser acessados de duas formas. O operador [ ] retorna uma sublista, enquanto [[ ]] retorna o conteúdo do elemento.

# Retorna uma sublista contendo o segundo elemento
minha_lista[2]
## [[1]]
## [1] 2026
class(minha_lista[2])
## [1] "list"
# Retorna o conteúdo do segundo elemento
minha_lista[[2]]
## [1] 2026
class(minha_lista[[2]])
## [1] "numeric"

Listas Nomeadas

Uma lista nomeada associa um nome a cada elemento, facilitando a organização e o acesso aos dados. Esse conceito é semelhante aos dicionários (dictionaries) em Python.

# Criando uma lista nomeada
estudante <- list(
    nome = "Ana Silva",
    nusp = 12345,
    notas = c(8.5, 9.0, 7.5),
    aprovado = TRUE
)

estudante
## $nome
## [1] "Ana Silva"
## 
## $nusp
## [1] 12345
## 
## $notas
## [1] 8.5 9.0 7.5
## 
## $aprovado
## [1] TRUE

Os elementos podem ser acessados pelo nome ou pela posição:

# Pelo nome com $
estudante$nome
## [1] "Ana Silva"
# Pelo nome com [[]]
estudante[["notas"]]
## [1] 8.5 9.0 7.5
# Primeiro elemento da lista
estudante[[1]]
## [1] "Ana Silva"
# Segundo elemento do vetor notas
estudante$notas[2]
## [1] 9

Também é possível modificar elementos existentes ou adicionar novos elementos à lista:

# Adicionar um novo elemento
estudante$curso <- "Economia"

# Alterar um elemento existente
estudante$nusp <- 99999
estudante
## $nome
## [1] "Ana Silva"
## 
## $nusp
## [1] 99999
## 
## $notas
## [1] 8.5 9.0 7.5
## 
## $aprovado
## [1] TRUE
## 
## $curso
## [1] "Economia"

Data Frames

O data frame é a estrutura de dados mais utilizada em análise de dados em R. Ele organiza informações em formato tabular, com linhas representando observações e colunas representando variáveis. É semelhante ao DataFrame da biblioteca pandas em Python.

Uma característica importante é que cada coluna pode possuir um tipo de dado diferente (numérico, texto, lógico etc.), mas todos os valores dentro de uma mesma coluna devem ser do mesmo tipo.

# Criar um data frame
df <- data.frame(
    nome = c("Ana", "Bruno", "Carlos", "Diana"),
    nota = c(8.5, 7.0, 9.5, 8.0),
    aprovado = c(TRUE, TRUE, TRUE, TRUE),
    stringsAsFactors = FALSE
)

df

Inspecionando um Data Frame

O R oferece diversas funções para explorar rapidamente a estrutura e o conteúdo de um data frame:

# Número de linhas
nrow(df)
## [1] 4
# Número de colunas
ncol(df)
## [1] 3
# Dimensões (linhas e colunas)
dim(df)
## [1] 4 3
# Nomes das colunas
names(df)
## [1] "nome"     "nota"     "aprovado"
# Estrutura resumida
str(df)
## 'data.frame':    4 obs. of  3 variables:
##  $ nome    : chr  "Ana" "Bruno" "Carlos" "Diana"
##  $ nota    : num  8.5 7 9.5 8
##  $ aprovado: logi  TRUE TRUE TRUE TRUE
# Estatísticas descritivas
summary(df)
##      nome                nota      aprovado      
##  Length:4           Min.   :7.00   Mode:logical  
##  Class :character   1st Qu.:7.75   TRUE:4        
##  Mode  :character   Median :8.25                 
##                     Mean   :8.25                 
##                     3rd Qu.:8.75                 
##                     Max.   :9.50

Acessando Dados

Como um data.frame pode ser visto como uma lista de colunas de mesmo comprimento, podemos utilizar diferentes formas de acesso.

# Operador $
df$nome
## [1] "Ana"    "Bruno"  "Carlos" "Diana"
# Nome da coluna
df[["nota"]]
## [1] 8.5 7.0 9.5 8.0
# Linha(s), coluna
df[, "nota"]
## [1] 8.5 7.0 9.5 8.0
# Segunda coluna
df[, 2]
## [1] 8.5 7.0 9.5 8.0

Também é possível acessar linhas específicas ou células individuais:

# Primeira linha
df[1, ]
# Data frame completo
df[, ]
# Elemento da linha 1, coluna nome
df[1, "nome"]
## [1] "Ana"
# Elemento da linha 2, coluna 2
df[2, 2]
## [1] 7

Filtrando Dados

A indexação lógica permite selecionar apenas as linhas que satisfazem uma determinada condição. Esse tipo de operação é semelhante ao boolean indexing utilizado no pandas.

# Alunos com nota superior a 8
df[df$nota > 8, ]

Criando Novas Colunas

Novas variáveis podem ser adicionadas ao data frame de forma simples, utilizando operações vetorizadas.

# Média da turma
df$media_turma <- mean(df$nota)

# Indicador de nota acima da média
df$acima_media <- df$nota > mean(df$nota)
df

Controle de Fluxo

Condicionais

Estruturas condicionais permitem executar diferentes blocos de código dependendo do resultado de uma condição lógica.

Em R, a principal estrutura de decisão é composta por if, else if e else, com sintaxe semelhante à do Python, mas utilizando chaves {} para delimitar os blocos de código.

# if / else if / else
nota <- 7.5

if (nota >= 9) {
    cat("Conceito A\n")
} else if (nota >= 7) {
    cat("Conceito B\n")
} else if (nota >= 5) {
    cat("Conceito C\n")
} else {
    cat("Reprovado\n")
}
## Conceito B

Quando a condição precisa ser avaliada para todos os elementos de um vetor, podemos utilizar a função ifelse(), que realiza a operação de forma vetorizada (similar ao método numpy.where() no Python).

# ifelse() — versão vetorizada
notas <- c(5.0, 8.0, 4.5, 9.0, 6.0)
resultado <- ifelse(notas >= 5, "Aprovado", "Reprovado")
resultado
## [1] "Aprovado"  "Aprovado"  "Reprovado" "Aprovado"  "Aprovado"

Laços

Laços de repetição permitem executar um mesmo bloco de código várias vezes. Em R, as estruturas mais comuns são for e while.

O laço for percorre os elementos de um vetor ou sequência, atribuindo cada valor sucessivamente à variável de iteração.

# for loop
for (i in 1:5) {
    cat("Iteração:", i, "\n")
}
## Iteração: 1 
## Iteração: 2 
## Iteração: 3 
## Iteração: 4 
## Iteração: 5
# Iterando sobre um vetor
frutas <- c("maçã", "banana", "laranja")

for (fruta in frutas) {
    cat("Fruta:", fruta, "\n")
}
## Fruta: maçã 
## Fruta: banana 
## Fruta: laranja

O laço while repete a execução de um bloco de código enquanto uma condição permanecer verdadeira.

# while loop
contador <- 1

while (contador <= 5) {
    cat("Contador:", contador, "\n")
    contador <- contador + 1
}
## Contador: 1 
## Contador: 2 
## Contador: 3 
## Contador: 4 
## Contador: 5

Importante: Embora os laços estejam disponíveis, eles são menos usados em R do que em outras linguagens, pois muitas operações são naturalmente vetorizadas.

notas <- c(5.0, 8.0, 4.5, 9.0, 6.0)
notas * 10
## [1] 50 80 45 90 60

Funções da família apply() também ajudam a substituir muitos laços explícitos.

A família apply no R (incluindo apply, lapply, sapply, tapply) é um conjunto de funções essenciais para aplicar operações repetitivas em vetores, listas ou matrizes, substituindo loops for por um código mais eficiente e limpo. Elas permitem aplicar funções como sum, mean ou personalizadas sobre linhas ou colunas.

  • apply(): Usada para matrizes ou data frames. Permite aplicar funções nas margens: 1 para linhas, 2 para colunas.
  • lapply(): Aplica uma função a cada elemento de uma lista ou vetor e sempre retorna uma lista.
  • sapply(): Similar ao lapply, mas tenta simplificar o resultado para um vetor ou matriz, se possível.
  • tapply(): Aplica uma função a subconjuntos de um vetor, baseando-se em um fator (agrupamento).
sapply(notas, function(x) x^2)
## [1] 25.00 64.00 20.25 81.00 36.00

Funções

Funções permitem encapsular trechos de código reutilizáveis em uma única unidade. Elas podem receber argumentos, realizar cálculos e retornar resultados.

# Definir uma função
calcular_media <- function(x) {
    soma <- sum(x)
    n <- length(x)
    return(soma / n)
}

calcular_media(c(8, 9, 7, 10))
## [1] 8.5

Argumentos também podem possuir valores padrão, que serão utilizados caso nenhum valor seja informado.

# Funções com múltiplos argumentos e valores padrão
calcular_conceito <- function(nota, corte_aprovacao = 5) {
    if (nota >= 9) {
        conceito <- "A"
    } else if (nota >= 7) {
        conceito <- "B"
    } else if (nota >= corte_aprovacao) {
        conceito <- "C"
    } else {
        conceito <- "F"
    }
    return(conceito)
}

calcular_conceito(8.5)
## [1] "B"
calcular_conceito(4.0)
## [1] "F"
calcular_conceito(4.0, corte_aprovacao = 4)
## [1] "C"

As funções também podem retornar listas, o que é útil quando queremos mais de um resultado.

# Funções podem retornar listas (múltiplos valores)
estatisticas <- function(x) {
    list(
        media    = mean(x),
        mediana  = median(x),
        desvio   = sd(x),
        minimo   = min(x),
        maximo   = max(x)
    )
}

notas <- c(8.5, 9.0, 7.5, 10.0, 6.0, 8.0)
resultado <- estatisticas(notas)
resultado$media
## [1] 8.166667
resultado$desvio
## [1] 1.36626

Em algumas situações, não é necessário criar uma função com nome. Nesses casos, podemos utilizar funções anônimas (funções lambda em Python), normalmente passadas como argumento para outras funções, como lapply, sapply, map (do pacote purrr), ou apply. Ideais para operações curtas e de uso único.

# Função anônima moderna (R 4.1+)
quadrado <- \(x) x^2
quadrado(5)
## [1] 25
sapply(1:5, \(x) x^2)
## [1]  1  4  9 16 25

Antes da versão 4.1, usava-se a palavra-chave function:

sapply(1:5, function(x) x^2)
## [1]  1  4  9 16 25

R vs Python: Comparação

Comparação R vs Python
Conceito Python R
Atribuição x = 5 x <- 5
Índice inicial 0 1
Tipo básico de dado list, dict vector
Listas heterogêneas list list
Tabular data pandas DataFrame data.frame / tibble
Strings str(“texto”) “texto”
Print print(x) cat(x) / print(x)
Importar biblioteca import pandas as pd library(tidyverse)
Comentário # comentário # comentário

Diferenças Importantes

1. Indexação em R começa em 1 (não em 0):

v <- c("a", "b", "c", "d")
v[1] # "a" — primeiro elemento (em Python seria v[0])
## [1] "a"
v[4] # "d" — último elemento (em Python seria v[-1] ou v[3])
## [1] "d"

2. Operações vetorizadas são nativas:

# Em Python com listas simples, isso geraria erro
# Precisaria de numpy: np.array(notas) + 1
notas <- c(7, 8, 9, 6)
notas + 1
## [1]  8  9 10  7
notas * 2
## [1] 14 16 18 12

3. O operador %in% verifica pertencimento (equivalente ao in do Python):

# Python: "banana" in ["maçã", "banana", "laranja"]
"banana" %in% c("maçã", "banana", "laranja")
## [1] TRUE
c(1, 2, 5) %in% c(1, 3, 5, 7)
## [1]  TRUE FALSE  TRUE

4. A família apply substitui muitos laços:

matriz <- matrix(1:12, nrow = 3)
matriz
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
# Soma por linha (margin = 1)
apply(matriz, 1, sum)
## [1] 22 26 30
# Soma por coluna (margin = 2)
apply(matriz, 2, sum)
## [1]  6 15 24 33
sapply(1:5, function(x) x^2)
## [1]  1  4  9 16 25

Exercícios

1. Crie um vetor com o PIB (em trilhões de reais) dos seguintes estados brasileiros: SP = 2.3, RJ = 0.9, MG = 0.8, RS = 0.6, PR = 0.5. Calcule a média, a soma total e identifique quais estados têm PIB acima da média.

2. Crie um data frame com informações de 5 países (nome, PIB per capita, população, continente). Depois: - Selecione apenas os países com PIB per capita > 10.000 - Adicione uma coluna com o PIB total (per capita × população)

3. Escreva uma função calcular_gini(x) que recebe um vetor de rendas e retorna o coeficiente de Gini. (Dica: o coeficiente de Gini é \(G = \frac{\sum_i \sum_j |x_i - x_j|}{2n^2\bar{x}}\))

4. Usando um laço for, crie um vetor com os 20 primeiros termos da sequência de Fibonacci. Depois refaça usando abordagem vetorizada.

5. Crie uma função que, dado um data frame com colunas receita e custo, calcule e retorne uma lista com: lucro total, margem média, número de operações lucrativas e número de operações com prejuízo.


Material baseado em: Wickham, H., Çetinkaya-Rundel, M. & Grolemund, G. (2023). R for Data Science (2ª ed.). O’Reilly. Disponível em: https://r4ds.hadley.nz/