peso <- 75
altura <- 1.70
peso[1] 75
altura[1] 1.7
Compreender e aplicar as principais estruturas de armazenamento de dados no R: vetores, matrizes, dataframes e listas.
Na aula anterior, vimos que o R permite criar objetos para armazenar informações.
A partir deste momento, deixamos de usar o R apenas como uma calculadora simples e começamos a organizar informações em estruturas de dados.
peso <- 75
altura <- 1.70
peso[1] 75
altura[1] 1.7
Vetores são estruturas que armazenam uma sequência de valores do mesmo tipo. Um vetor pode conter números, textos ou valores lógicos.
Vetores são uma das estruturas mais importantes do R. Muitas análises estatísticas começam com a criação ou manipulação de vetores.
idades <- c(34, 45, 29)
nomes <- c("Ana", "João", "Fernanda")
respondeu <- c(TRUE, FALSE, TRUE)
idades[1] 34 45 29
nomes[1] "Ana" "João" "Fernanda"
respondeu[1] TRUE FALSE TRUE
Todos os elementos de um vetor devem ser do mesmo tipo. Quando tipos diferentes são misturados, o R faz coerção automática.
vetor_misto <- c(10, 20, "Ana")
vetor_misto[1] "10" "20" "Ana"
class(vetor_misto)[1] "character"
sequencia_1 <- 1:10
sequencia_2 <- seq(0, 20, by = 2)
repeticao_1 <- rep(5, times = 8)
repeticao_2 <- rep(c(1, 2, 3), times = 3)
sequencia_1 [1] 1 2 3 4 5 6 7 8 9 10
sequencia_2 [1] 0 2 4 6 8 10 12 14 16 18 20
repeticao_1[1] 5 5 5 5 5 5 5 5
repeticao_2[1] 1 2 3 1 2 3 1 2 3
Quando realizamos operações matemáticas com vetores, o R aplica a operação elemento por elemento.
x <- c(10, 20, 30)
y <- c(1, 2, 3)
x + y[1] 11 22 33
x - y[1] 9 18 27
x * y[1] 10 40 90
x / y[1] 10 10 10
x^2[1] 100 400 900
O produto escalar multiplica os elementos correspondentes de dois vetores e soma os resultados.
a <- c(1, 2, 3)
b <- c(4, 5, 6)
a %*% b [,1]
[1,] 32
No exemplo anterior, o R calcula:
\(1 \cdot 4 + 2 \cdot 5 + 3 \cdot 6\)
No R, a primeira posição de um vetor é sempre a posição 1.
notas <- c(8.5, 7.0, 9.2, 6.8, 10)
notas[1][1] 8.5
notas[3][1] 9.2
notas[c(2, 4)][1] 7.0 6.8
A indexação lógica é uma das ferramentas mais úteis do R, pois permite selecionar valores a partir de condições.
notas <- c(8.5, 7.0, 9.2, 6.8, 10)
notas > 7[1] TRUE FALSE TRUE FALSE TRUE
notas[notas > 7][1] 8.5 9.2 10.0
notas[notas >= 9][1] 9.2 10.0
notas <- c(8.5, 7.0, 9.2, 6.8, 10)
sum(notas)[1] 41.5
mean(notas)[1] 8.3
median(notas)[1] 8.5
min(notas)[1] 6.8
max(notas)[1] 10
length(notas)[1] 5
sort(notas)[1] 6.8 7.0 8.5 9.2 10.0
rev(notas)[1] 10.0 6.8 9.2 7.0 8.5
summary(notas) Min. 1st Qu. Median Mean 3rd Qu. Max.
6.8 7.0 8.5 8.3 9.2 10.0
O valor NA representa ausência de informação. Muitas funções precisam do argumento na.rm = TRUE para ignorar esses valores.
notas_com_na <- c(8.5, NA, 7.0, 9.2, NA, 10)
is.na(notas_com_na)[1] FALSE TRUE FALSE FALSE TRUE FALSE
notas_com_na[!is.na(notas_com_na)][1] 8.5 7.0 9.2 10.0
mean(notas_com_na, na.rm = TRUE)[1] 8.675
Matrizes são estruturas bidimensionais, formadas por linhas e colunas.
Podemos pensar em uma matriz como uma tabela numérica. Diferentemente do dataframe, uma matriz deve armazenar dados do mesmo tipo.
matriz_1 <- matrix(1:9, ncol = 3)
matriz_1 [,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Por padrão, o R preenche a matriz por colunas.
matriz_2 <- matrix(1:9, ncol = 3, byrow = TRUE)
matriz_2 [,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
nrow(matriz_2)[1] 3
ncol(matriz_2)[1] 3
dim(matriz_2)[1] 3 3
length(matriz_2)[1] 9
Para acessar elementos de uma matriz, usamos a estrutura [linha, coluna].
matriz_2 [,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
matriz_2[1, 1][1] 1
matriz_2[2, 3][1] 6
matriz_2[1, ][1] 1 2 3
matriz_2[, 2][1] 2 5 8
matriz_2[2, 2] <- 100
matriz_2 [,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 100 6
[3,] 7 8 9
A <- matrix(1:4, ncol = 2)
B <- matrix(c(2, 4, 6, 8), ncol = 2)
A [,1] [,2]
[1,] 1 3
[2,] 2 4
B [,1] [,2]
[1,] 2 6
[2,] 4 8
A + B [,1] [,2]
[1,] 3 9
[2,] 6 12
A - B [,1] [,2]
[1,] -1 -3
[2,] -2 -4
A * B [,1] [,2]
[1,] 2 18
[2,] 8 32
A %*% B [,1] [,2]
[1,] 14 30
[2,] 20 44
O operador * faz multiplicação elemento a elemento.
O operador %*% faz multiplicação matricial.
M <- matrix(1:9, ncol = 3, byrow = TRUE)
M [,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
t(M) [,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
diag(M)[1] 1 5 9
rowSums(M)[1] 6 15 24
colSums(M)[1] 12 15 18
rowMeans(M)[1] 2 5 8
colMeans(M)[1] 4 5 6
Dataframes são estruturas em formato de tabela. Diferentemente das matrizes, cada coluna pode ter um tipo diferente.
O dataframe é uma das estruturas mais usadas em análise de dados, pois se parece com uma planilha.
pacientes <- data.frame(
nome = c("Ana", "João", "Fernanda"),
idade = c(34, 45, 29),
peso = c(68.5, 82.0, 59.3),
altura = c(1.65, 1.78, 1.60),
respondeu = c(TRUE, FALSE, TRUE)
)
pacientesstr(pacientes)'data.frame': 3 obs. of 5 variables:
$ nome : chr "Ana" "João" "Fernanda"
$ idade : num 34 45 29
$ peso : num 68.5 82 59.3
$ altura : num 1.65 1.78 1.6
$ respondeu: logi TRUE FALSE TRUE
dim(pacientes)[1] 3 5
nrow(pacientes)[1] 3
ncol(pacientes)[1] 5
names(pacientes)[1] "nome" "idade" "peso" "altura" "respondeu"
summary(pacientes) nome idade peso altura
Length:3 Min. :29.0 Min. :59.30 Min. :1.600
Class :character 1st Qu.:31.5 1st Qu.:63.90 1st Qu.:1.625
Mode :character Median :34.0 Median :68.50 Median :1.650
Mean :36.0 Mean :69.93 Mean :1.677
3rd Qu.:39.5 3rd Qu.:75.25 3rd Qu.:1.715
Max. :45.0 Max. :82.00 Max. :1.780
respondeu
Mode :logical
FALSE:1
TRUE :2
pacientes$nome[1] "Ana" "João" "Fernanda"
pacientes$idade[1] 34 45 29
pacientes[, "peso"][1] 68.5 82.0 59.3
pacientes[1, ]pacientes[2, ]pacientes[1, "nome"][1] "Ana"
pacientes[3, "peso"][1] 59.3
Como cada coluna de um dataframe pode ser tratada como um vetor, podemos criar novas variáveis a partir de cálculos.
pacientes$imc <- pacientes$peso / pacientes$altura^2
pacientespacientes[pacientes$idade > 30, ]pacientes[pacientes$imc >= 25, ]pacientes[pacientes$respondeu == TRUE, ]Em filtros lógicos, usamos == para comparação, e não =.
Quando queremos adicionar uma nova observação ao dataframe, podemos usar rbind(). Para isso, a nova linha precisa ter as mesmas colunas do dataframe original.
novo_paciente <- data.frame(
nome = "Carlos",
idade = 31,
peso = 75.2,
altura = 1.72,
respondeu = TRUE,
imc = 75.2 / 1.72^2
)
pacientes <- rbind(pacientes, novo_paciente)
pacientes%in%O operador %in% verifica se os valores de um vetor pertencem a um conjunto de valores. Ele é muito útil para criar variáveis lógicas a partir de categorias.
pacientes$grupo_idade <- pacientes$idade %in% c(29, 31, 34)
pacientesListas são estruturas flexíveis que podem armazenar diferentes tipos de objetos.
Uma lista pode guardar vetores, matrizes, dataframes, textos, números e até outras listas.
minha_lista <- list(
nomes = c("Ana", "João", "Fernanda"),
notas = c(8.5, 7.0, 9.2),
matriz = matrix(1:4, ncol = 2),
dataframe = pacientes,
texto = "Exemplo de lista no R"
)
minha_lista$nomes
[1] "Ana" "João" "Fernanda"
$notas
[1] 8.5 7.0 9.2
$matriz
[,1] [,2]
[1,] 1 3
[2,] 2 4
$dataframe
nome idade peso altura respondeu imc grupo_idade
1 Ana 34 68.5 1.65 TRUE 25.16070 TRUE
2 João 45 82.0 1.78 FALSE 25.88057 FALSE
3 Fernanda 29 59.3 1.60 TRUE 23.16406 TRUE
4 Carlos 31 75.2 1.72 TRUE 25.41915 TRUE
$texto
[1] "Exemplo de lista no R"
minha_lista$nomes[1] "Ana" "João" "Fernanda"
minha_lista$notas[1] 8.5 7.0 9.2
minha_lista$matriz [,1] [,2]
[1,] 1 3
[2,] 2 4
minha_lista[[1]][1] "Ana" "João" "Fernanda"
minha_lista[[4]]O operador $ acessa elementos pelo nome.
O operador [[ ]] acessa elementos pela posição.
str(minha_lista)List of 5
$ nomes : chr [1:3] "Ana" "João" "Fernanda"
$ notas : num [1:3] 8.5 7 9.2
$ matriz : int [1:2, 1:2] 1 2 3 4
$ dataframe:'data.frame': 4 obs. of 7 variables:
..$ nome : chr [1:4] "Ana" "João" "Fernanda" "Carlos"
..$ idade : num [1:4] 34 45 29 31
..$ peso : num [1:4] 68.5 82 59.3 75.2
..$ altura : num [1:4] 1.65 1.78 1.6 1.72
..$ respondeu : logi [1:4] TRUE FALSE TRUE TRUE
..$ imc : num [1:4] 25.2 25.9 23.2 25.4
..$ grupo_idade: logi [1:4] TRUE FALSE TRUE TRUE
$ texto : chr "Exemplo de lista no R"
length(minha_lista)[1] 5
names(minha_lista)[1] "nomes" "notas" "matriz" "dataframe" "texto"