R: Matrizes e tabelas
Última atualização: 2026-08-26
Na aula anterior, aprendemos sobre vetores “unidimensionais”. Nesta aula, passaremos aos conceitos “bidimensionais” e “multidimensionais” — matrizes e arrays. As matrizes são a base da análise de dados (planilhas do Excel, pixels de imagens e pesos de redes neurais são todos matrizes), portanto, vamos nos certificar de compreendê-las plenamente nesta aula.
O “coração” das matrizes é a família de funções apply() — ela nos permite realizar operações por linha, coluna ou dimensão sem precisar escrever loops. É nesse ponto que o R é mais conciso que o Python.
1. O que você vai aprender
- matrix() cria uma matriz (preenchida por linhas ou colunas)
- Propriedades da matriz (dim, nrow, ncol, rownames, colnames)
- rbind/cbind: Fusão de matrizes
- aplicar funções de família (apply/lapply/sapply/tapply/mapply)
- Extensões multidimensionais do tipo de dados
array - Operações com matrizes (transposição
%*%, inversasolve()) - Prática: Estatísticas de transcrição
2. A história de um histórico escolar
(1) Desafio: Compilação de notas em várias disciplinas
Xiao Zhao é funcionário responsável pelos assuntos acadêmicos. Os históricos escolares de cinco alunos em três disciplinas são os seguintes:
Mathematics Chinese Language English
Alice 85 78 92
Bob 72 88 80
Charlie 90 85 87
Diana 65 70 75
Eve 95 92 88
Calcule: ① a pontuação total de cada aluno; ② a média de cada disciplina; ③ identifique o aluno com a maior pontuação em matemática.
Se você fosse fazer isso usando fórmulas do Excel, levaria uma eternidade; se fosse fazer em Python, teria que usar loops aninhados—
(2) Solução utilizando R
# 5x3 Matrix
scores <- matrix(c(85, 78, 92,
72, 88, 80,
90, 85, 87,
65, 70, 75,
95, 92, 88),
nrow = 5, byrow = TRUE)
colnames(scores) <- c("Mathematics", "Chinese Language", "English")
rownames(scores) <- c("Alice", "Bob", "Charlie", "Diana", "Eve")
# 1. Each Student's Total Score(Sum in One Line)
row_sums <- apply(scores, 1, sum)
# 2. Average per subject(Calculate the average for a column)
col_means <- apply(scores, 2, mean)
# 3. Find the highest score in math
top_math <- which.max(scores[, "Mathematics"])
Cinco linhas de código para resolver três tarefas. Esse é o poder das matrizes e da função apply.
3. A essência das matrizes: vetores bidimensionais
(1) Conversão de vetores em matrizes
graph LR
A["One-dimensional vector c 1,2,3,4,5,6"] --> B["reshape into 2x3 Matrix"]
B --> C["1 2 3 / 4 5 6"]
B --> D["1 4 / 2 5 / 3 6"]
style A fill:#cce5ff
style B fill:#fff3cd
# One-dimensional vector
v <- 1:6
v
# [1] 1 2 3 4 5 6
# Convert to 2 row 3 List of Matrices
m <- matrix(v, nrow = 2, ncol = 3)
m
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 2 4 6
(2) As quatro propriedades fundamentais das matrizes
| Propriedade | Significado | Exemplo |
|---|---|---|
dim(m) |
vetor dimensional | dim(m) → c(2, 3) |
nrow(m) |
Número da linha | nrow(m) → 2 |
ncol(m) |
Número de linhas | ncol(m) → 3 |
length(m) |
Número total de elementos | length(m) → 6 |
m <- matrix(1:6, nrow = 2)
dim(m) # [1] 2 3
nrow(m) # [1] 2
ncol(m) # [1] 3
length(m) # [1] 6 ← Total Number of Elements
4. matrix(): Criar uma matriz
(1) Sintaxe básica
matrix(data, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
(2) 4 maneiras de criar
# 1. Provide the data directly + Number of rows and columns
m1 <- matrix(1:6, nrow = 2)
# [,1] [,2] [,3]
# [1,] 1 3 5 ← Fill by column by default
# [2,] 2 4 6
# 2. byrow = TRUE(Fill by Row)
m2 <- matrix(1:6, nrow = 2, byrow = TRUE)
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# 3. Add row and column names
m3 <- matrix(1:6, nrow = 2, byrow = TRUE,
dimnames = list(c("row1", "row2"), c("colA", "colB", "colC")))
# colA colB colC
# row1 1 2 3
# row2 4 5 6
# 4. Specify only nrow,ncol Automatic Inference
m4 <- matrix(1:6, nrow = 3) # 3 row 2 col
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
byrow = FALSE é a configuração padrão (preenchimento por coluna). Na maioria dos casos, queremos preencher por linha (um aluno por linha/um registro), portanto, é necessário especificar explicitamente byrow = TRUE.
(3) Adicionar rótulos às colunas e linhas (para facilitar a leitura)
m <- matrix(1:6, nrow = 2, byrow = TRUE)
rownames(m) <- c("Alice", "Bob")
colnames(m) <- c("Mathematics", "Chinese Language", "English")
m
# Mathematics Chinese Language English
# Alice 1 2 3
# Bob 4 5 6
5. Acesso aos elementos da matriz
(1) Três maneiras de acessar
| Método | Sintaxe | Finalidade |
|---|---|---|
[i, j] |
Linha i, coluna j | Elemento único |
[i, ] |
Linha i | Linha inteira |
[, j] |
Coluna j | Coluna inteira |
[i, "col_name"] |
Uma coluna na linha i | Por nome |
m <- matrix(1:9, nrow = 3, byrow = TRUE,
dimnames = list(c("Alice", "Bob", "Charlie"),
c("Mathematics", "Chinese Language", "English")))
m
# Mathematics Chinese Language English
# Alice 1 2 3
# Bob 4 5 6
# Charlie 7 8 9
# A single element
m[2, 3] # [1] 6
m["Bob", "English"] # [1] 6
# Entire row
m[1, ] # Mathematics 1 Chinese Language 2 English 3
m["Alice", ] # Ibid.
# Align
m[, 1] # Alice 1 Bob 4 Charlie 7
m[, "Mathematics"] # Ibid.
(2) Índice lógico
# Find the math scores > 5 students
m[m[, "Mathematics"] > 5, ]
# Mathematics Chinese Language English
# Bob 4 ... ← Will not be selected
# Charlie 7 8 9
6. rbind/cbind: Combinação de matrizes
graph TB
A["Matrix A 3x2"] --> C["rbind Concatenate by row"]
B["Matrix B 2x2"] --> C
C --> D["New Matrix 5x2"]
E["Matrix A 3x2"] --> F["cbind Concatenate by Column"]
G["Matrix B 3x2"] --> F
F --> H["New Matrix 3x4"]
style A fill:#cce5ff
style B fill:#cce5ff
style E fill:#d4edda
style G fill:#d4edda
a <- matrix(1:6, nrow = 3, byrow = TRUE)
b <- matrix(7:12, nrow = 3, byrow = TRUE)
# Concatenate by row(Sum of Rows)
rbind(a, b)
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
# [3,] 5 6
# [4,] 7 8
# [5,] 9 10
# [6,] 11 12
# Concatenate by Column(Sum of a Series)
cbind(a, b)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 7 8
# [2,] 3 4 9 10
# [3,] 5 6 11 12
rbind(a, b) requer ncol(a) == ncol(b); cbind(a, b) requer nrow(a) == nrow(b); caso contrário, ocorrerá um erro.
7. A série de funções apply (A essência)
(1) Por que o apply é necessário?
Os loops no R são muito lentos, mas o apply nos permite realizar operações linha por linha ou coluna por coluna sem precisar escrever loops:
m <- matrix(1:9, nrow = 3)
# Find the sum of each row(No need for a loop)
apply(m, 1, sum)
# [1] 12 15 18
# Find the sum of each column
apply(m, 2, sum)
# [1] 12 15 18
(2) A essência de apply()
apply(X, MARGIN, FUN)
| Parâmetro | Significado | Valores possíveis |
|---|---|---|
X |
Matriz/Array | matriz / array |
MARGIN |
Dimensão | 1=linha, 2=coluna, c(1,2)=linha e coluna |
FUN |
Função a ser aplicada | sum mean max function(x) ... |
# 1=row(Process by row),2=col(Process by Column)
apply(m, 1, mean) # Average per line
apply(m, 2, max) # Maximum per column
# Custom Functions
apply(m, 1, function(x) max(x) - min(x)) # Range per row
(3) As 5 funções da família apply
| Função | Entrada | Saída | Usos típicos |
|---|---|---|---|
apply() |
Matrizes/Matrizes | Vetores/Matrizes | Operações em linhas/colunas |
lapply() |
Listas/Vetores | Listas | Processamento de listas |
sapply() |
Listas/Vetores | Vetores/Matrizes | lapply simplificado |
tapply() |
Vetores + Grupos | Matrizes | Estatísticas de grupos |
mapply() |
Multiveador | Lista/Vetor | Função com vários argumentos |
(4) lapply() x sapply()
# lapply Back to List
numbers <- list(a = 1:3, b = 4:6, c = 7:9)
result_l <- lapply(numbers, sum)
# $a 6
# $b 15
# $c 24
# sapply Return Vector(More commonly used)
result_s <- sapply(numbers, sum)
# a b c
# 6 15 24
sapply() primeiro — é mais prático para retornar vetores. lapply() é mais comumente usado em pipelines de programação funcional.
(5) Estatísticas agrupadas com a função tapply()
# 5 Students 3 Course Grades, grouped by "Gender"
scores <- c(85, 78, 92, 72, 88, 80, 90, 85, 87, 65, 70, 75, 95, 92, 88)
gender <- c("M", "F", "M", "M", "F", "F", "M", "M", "F", "M", "F", "M", "F", "M", "F")
# Calculate the average by gender
tapply(scores, gender, mean)
# F M
# 84.6 81.5
tapply() é extremamente comum ao se realizar “estatísticas de grupo” — mas usar dplyr::group_by() | summarise() na próxima fase seria mais elegante.
(6) mapply() — Uma função com vários argumentos
# Sum the corresponding elements of two vectors
mapply(function(a, b) a + b, 1:3, 10:12)
# [1] 11 13 15
8. Matrizes: Extensões multidimensionais
# 2x3x4 a three-dimensional array
arr <- array(1:24, dim = c(2, 3, 4))
# 1st 2x3 Matrix
arr[, , 1]
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 2 4 6
# apply Supports multidimensional operations
apply(arr, c(1, 2), mean) # Regarding No. 3 Find the average
data.frame (Próxima Etapa) e array (Imagens/Física) são as abordagens mais comuns para dados multidimensionais.
9. Operações com matrizes (álgebra linear)
| Operação | Sintaxe | Descrição |
|---|---|---|
| Transpor | t(m) |
De linha para coluna |
| Multiplicação de matrizes | m1 %*% m2 |
Multiplicação em álgebra linear |
| Multiplicação elemento a elemento | m1 * m2 |
Multiplicação elemento a elemento correspondente |
| Inversa | solve(m) |
Matriz inversa |
| Soma (linhas/colunas) | rowSums(m) / colSums(m) |
Soma rápida |
m <- matrix(1:4, nrow = 2)
# [,1] [,2]
# [1,] 1 3
# [2,] 2 4
# Transpose
t(m)
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
# Matrix Multiplication (use m %*% m)
m %*% m
# [,1] [,2]
# [1,] 7 15
# [2,] 10 22
# Inverse
solve(m)
# [,1] [,2]
# [1,] -2 1.5
# [2,] 1 -0.5
10. Exemplo completo: Análise abrangente de um histórico escolar
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que combina todas as matrizes e funções apply desta lição.
▶ Exemplo: Análise abrangente das notas da turma
# ============================================
# Comprehensive Analysis of Class Performance
# Features:5 Student 3 A Comprehensive Analysis of the Course Grade Matrix
# ============================================
# 1. Create a Grade Matrix(Fill by Row:One student per line)
scores <- matrix(c(
85, 78, 92, # Alice
72, 88, 80, # Bob
90, 85, 87, # Charlie
65, 70, 75, # Diana
95, 92, 88 # Eve
), nrow = 5, byrow = TRUE)
# Add row and column names
rownames(scores) <- c("Alice", "Bob", "Charlie", "Diana", "Eve")
colnames(scores) <- c("Mathematics", "Chinese Language", "English")
cat("=== Grade Matrix ===\n")
print(scores)
# 2. Each Student's Total Score(Sum by Row)
cat("\n=== Student's Total Score ===\n")
row_totals <- apply(scores, 1, sum)
print(row_totals)
# 3. Average per subject/Highest/Lowest(Tally by Column)
cat("\n=== Statistics by Subject ===\n")
col_stats <- apply(scores, 2, function(x) {
c(mean = round(mean(x), 2),
max = max(x),
min = min(x),
sd = round(sd(x), 2))
})
print(col_stats)
# 4. Average score per student(Calculate the average by row)
cat("\n=== Average Student Score ===\n")
row_means <- apply(scores, 1, mean)
print(round(row_means, 2))
# 5. Identify the student with the highest math score
top_math <- which.max(scores[, "Mathematics"])
cat("\nHighest Score in Math:", rownames(scores)[top_math], "(", max(scores[, "Mathematics"]), "min)\n")
# 6. Identify the student with the highest total score
top_total <- which.max(row_totals)
cat("Highest Total Score:", rownames(scores)[top_total], "(", max(row_totals), "min)\n")
# 7. Find a single subject < 70 students(Using Logical Indexes)
fail <- scores < 70
cat("\nFailed Courses(< 70):\n")
print(scores)
cat("\nDid I fail?(TRUE = Fail):\n")
print(fail)
# 8. Overall Ranking
cat("\n=== Overall Ranking(Sort by total score in descending order)===\n")
ranking <- order(row_totals, decreasing = TRUE)
result <- data.frame(
Ranking = 1:5,
Name = rownames(scores)[ranking],
Total Score = row_totals[ranking],
Average = round(row_totals[ranking] / 3, 2)
)
print(result)
Resultado esperado (trecho):
=== Grade Matrix ===
Mathematics Chinese Language English
Alice 85 78 92
Bob 72 88 80
Charlie 90 85 87
Diana 65 70 75
Eve 95 92 88
=== Student's Total Score ===
Alice Bob Charlie Diana Eve
255 240 262 210 275
=== Average Student Score ===
Alice Bob Charlie Diana Eve
85.00 80.00 87.33 70.00 91.67
=== Overall Ranking(Sort by total score in descending order)===
Ranking Name Total Score Average
1 1 Eve 275 91.67
2 2 Charlie 262 87.33
3 3 Alice 255 85.00
4 4 Bob 240 80.00
5 5 Diana 210 70.00
❓ Perguntas Frequentes
P: Qual é a diferença entre
byrow = TRUEe FALSE? R:matrix(1:6, nrow=2, byrow=FALSE)(padrão) preenche por coluna:1 3 5 / 2 4 6;byrow=TRUEpreenche por linha:1 2 3 / 4 5 6. Em cenários de ciência de dados, os dados são quase sempre preenchidos por linha (uma linha por amostra).
P: Como faço para escolher entre
apply()e um loop “for”? R: Useapply()sempre que possível — os loops “R” são de 10 a 100 vezes mais lentos. Useapply(m, 1, fun)em vez de “iterar por linha” eapply(m, 2, fun)em vez de “iterar por coluna”.
P: Como faço para escolher entre
lapply()esapply()? R: Os tipos de retorno são diferentes —lapplyretorna uma lista, enquantosapplysimplifica o resultado para um vetor ou matriz sempre que possível. Para o uso cotidiano,sapplyé suficiente (o resultado é mais conciso).
P: Qual é a diferença entre
%*%e*? R:%*%é a multiplicação de matrizes (seguindo as regras da álgebra linear), enquanto*é a multiplicação elemento a elemento (multiplicando os elementos correspondentes). A regressão linear, as redes neurais e outras aplicações requerem%*%.
P:
tapply()Como isso é utilizado em projetos reais? R:tapply(x, group, fun)Para realizar rapidamente “estatísticas agrupadas” — agrupando por gênero, região, mês etc. No entanto, na próxima fase, usardplyr::group_by() \| summarise()é uma abordagem mais elegante;tapplyserve como base.
📖 Resumo
- Uma matriz é um vetor bidimensional, enquanto um array é um vetor multidimensional;
matrix()criação,array()extensão para múltiplas dimensões byrow = TRUEPreenchimento por linha (padrão de ciência de dados),FALSE(padrão) Preenchimento por coluna- Método de acesso
m[i, j]/m[i, ]/m[, j]/m["row", "col"] rbind()Ordenar por linha,cbind()Ordenar por coluna- aplicar família:
apply()Por dimensão,lapply()Lista → Lista,sapply()Lista → Vetor,tapply()Estatísticas agrupadas,mapply()Parâmetros múltiplos - Operações matriciais:
t()Transposição,%*%Multiplicação de matrizes,solve()Inversa de matriz,rowSums()colSums()Soma rápida - Use
applyem vez de loops: os loops no R são de 10 a 100 vezes mais lentos; se puder usarapply, não escreva loops
📝 Exercícios
-
Problema básico: Crie uma matriz 4×4 com elementos que variam de 1 a 16, preenchida linha por linha, com os rótulos de linha e coluna
c("A","B","C","D")ec("X","Y","Z","W"), respectivamente. Imprima a matriz e verifique se os rótulos de linha e coluna estão corretos. -
Problema básico: Use
apply()para calcular as somas das linhas, as somas das colunas, as médias das linhas e os valores máximos das colunas da matriz do problema anterior. -
Exercício básico: Use
rbind()ecbind()para somar duas matrizes 3×3 (que você mesmo construirá) e verifique como o número de linhas e colunas se altera. -
Problema avançado: Simule as notas de 6 alunos em 4 disciplinas: ① Use
apply()para calcular a pontuação total de cada aluno; ② Useapply()para calcular a média de cada disciplina; ③ Usewhich.max()para descobrir o nome do aluno com a maior pontuação em cada disciplina; ④ Useorder()para classificar os alunos. -
Desafio: Escreva um script para realizar uma “análise em camadas” das notas de 100 alunos em 5 disciplinas: ① Use
tapply()para calcular a média geral agrupando por “gênero”; ② Determine o número de alunos que obtiveram nota 90 ou mais em matemática, mas foram reprovados em inglês (nota < 60); ③ Calcule o desvio padrão para as 5 disciplinas de cada aluno (usandoapply()+ uma função personalizada).