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



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:

TEXT 📖 Somente leitura
       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

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

100%
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
R
# 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
R
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

R
matrix(data, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)

(2) 4 maneiras de criar

R
# 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
⚠️ Observação: 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)

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

R
# 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

100%
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
R
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
⚠️ Observação: 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:

R
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()

R
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) ...
R
# 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()

R
# 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
💡 Dica: Use 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()

R
# 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
💡 Dica: 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

R
# 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

R
# 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
💡 Dica: Os arrays raramente são usados no desenvolvimento práticodata.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
R
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

R 📖 Somente leitura
# ============================================
# 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)
43 linhas de lógica (limite de 40, somente leitura)

Resultado esperado (trecho):

TEXT 📖 Somente leitura
=== 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 = TRUE e FALSE? R: matrix(1:6, nrow=2, byrow=FALSE) (padrão) preenche por coluna: 1 3 5 / 2 4 6; byrow=TRUE preenche 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: Use apply() sempre que possível — os loops “R” são de 10 a 100 vezes mais lentos. Use apply(m, 1, fun) em vez de “iterar por linha” e apply(m, 2, fun) em vez de “iterar por coluna”.

P: Como faço para escolher entre lapply() e sapply()? R: Os tipos de retorno são diferentes — lapply retorna uma lista, enquanto sapply simplifica 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, usar dplyr::group_by() \| summarise() é uma abordagem mais elegante; tapply serve como base.


📖 Resumo


📝 Exercícios

  1. 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") e c("X","Y","Z","W"), respectivamente. Imprima a matriz e verifique se os rótulos de linha e coluna estão corretos.

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

  3. Exercício básico: Use rbind() e cbind() para somar duas matrizes 3×3 (que você mesmo construirá) e verifique como o número de linhas e colunas se altera.

  4. Problema avançado: Simule as notas de 6 alunos em 4 disciplinas: ① Use apply() para calcular a pontuação total de cada aluno; ② Use apply() para calcular a média de cada disciplina; ③ Use which.max() para descobrir o nome do aluno com a maior pontuação em cada disciplina; ④ Use order() para classificar os alunos.

  5. 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 (usando apply() + uma função personalizada).

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%