Menu

Matrizes no R: matrix(), cbind, rbind e Álgebra de Matrizes

Como construir matrizes com matrix(), cbind() e rbind(), indexar linhas e colunas, e manter o * elemento a elemento separado da verdadeira multiplicação de matrizes %*%.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Uma Matriz É um Vetor com Dimensões

Uma matriz no R é um retângulo de valores - linhas e colunas - em que toda célula guarda o mesmo tipo, normalmente números. Por baixo dos panos ela é literalmente um vetor com um atributo dim grampeado, o que explica a maior parte do seu comportamento: um único tipo do começo ao fim, matemática vetorizada em toda parte.

Você constrói uma remodelando um vetor com matrix():

Seis valores, duas linhas - o R deduz que são necessárias três colunas. dim() reporta as duas dimensões de uma vez como 2 3; nrow() e ncol() as dão separadamente.

Olhe com atenção a matriz impressa: os valores descem 1 2 pela primeira coluna, depois 3 4 pela seguinte. O R preenche matrizes coluna por coluna por padrão. Se seus dados se leem linha por linha - que é como humanos normalmente os escrevem - diga isso com byrow = TRUE:

Agora a primeira linha é 1 2 3. Esquecer byrow = TRUE não dá erro - silenciosamente entrega um arranjo com cara de transposto dos mesmos números, então crie o hábito de conferir o layout impresso sempre que construir uma matriz a partir de valores brutos.

Indexação: m[linha, coluna]

A indexação de matrizes usa duas posições dentro de um único par de colchetes, linha antes da vírgula, coluna depois - as duas contando a partir de 1:

Deixar uma posição vazia significa "todas": m[1, ] é a primeira linha inteira, m[, 2] a segunda coluna inteira. Repare que ambas voltam como vetores simples - o R descarta a dimensão que colapsou para tamanho 1. Isso é conveniente no modo interativo e uma armadilha em código, porque uma função que espera uma matriz vai engasgar com o vetor. Peça ao R que preserve o formato com drop = FALSE:

dim() agora reporta 1 3 - ainda é uma matriz. Toda vez que você fatiar uma única linha ou coluna dentro de uma função, escreva drop = FALSE; o bug que isso evita (código que funciona com dados largos e quebra com dados de uma coluna) é péssimo de rastrear.

Máscaras lógicas também funcionam aqui: m[m > 3] retorna todas as células acima de 3, como um vetor.

Construindo com cbind() e rbind()

Em vez de remodelar um vetor longo, você pode montar uma matriz a partir de pedaços: cbind() une vetores como colunas, rbind() como linhas. As mesmas funções também estendem uma matriz existente:

Os nomes viajam junto com os vetores: cbind() usou heights e weights como nomes de coluna automaticamente, o que mantém a matriz impressa legível. As duas funções exigem que os comprimentos batam (com reciclagem para valores de comprimento 1); ligar um vetor de comprimento 3 a uma matriz de 4 linhas gera um aviso.

Nomes de coluna e de linha também podem ser definidos diretamente via colnames(m) <- ... e rownames(m) <- ..., depois do que você pode indexar por nome: people[, "weights"].

* Elemento a Elemento vs Verdadeira Multiplicação de Matrizes %*%

Aqui está a distinção que mais importa neste artigo inteiro. O R tem dois operadores de multiplicação para matrizes, e eles calculam coisas completamente diferentes:

  • a * a é elemento a elemento: cada célula multiplicada pela célula correspondente. 1 2 3 4 viram 1 4 9 16, arranjados no mesmo formato. Isso é só aritmética vetorizada, o mesmo * que você usa em vetores.
  • a %*% a é multiplicação de matrizes da álgebra linear - cada célula do resultado é uma linha da primeira matriz vezes uma coluna da segunda, somadas. A mesma entrada dá 7 10 15 22: números totalmente diferentes.

Rode o trecho e compare as duas saídas lado a lado; ver os resultados divergirem com entradas idênticas é o que fixa a distinção. Se você escrever * onde a matemática pede %*%, o R não vai avisar - os formatos são compatíveis dos dois jeitos para matrizes quadradas - você só recebe números errados. Em código estatístico (matrizes de covariância, álgebra de modelos lineares) esse é um dos bugs silenciosos clássicos.

t() transpõe - troca linhas por colunas - e aparece o tempo todo ao lado de %*% porque a multiplicação de matrizes exige que as dimensões internas coincidam:

Para completar: solve(m) inverte uma matriz, e %*% com um vetor o trata como uma matriz de uma coluna. Isso é tão fundo quanto a maior parte do trabalho com dados precisa ir.

Resumos de Linhas e Colunas

Somar ou tirar médias ao longo de linhas e colunas é tão comum que o R traz funções dedicadas e rápidas para isso:

rowSums() colapsa cada linha em um número (6 15 aqui), colSums() faz o mesmo por coluna (5 7 9), e as variantes Means calculam a média em vez da soma. Prefira essas a laços feitos à mão ou mesmo a apply(m, 1, sum) - são mais claras e mais rápidas. Para resumos que essas quatro não cobrem (digamos, o máximo por coluna), a família apply é a ferramenta geral: apply(m, 2, max).

Matriz ou Data Frame?

Ambos são retangulares, então qual escolher?

  • Matriz: toda célula do mesmo tipo, e a matemática importa. Computação numérica, álgebra linear, cálculos de distância, grades tipo imagem. Matrizes são mais enxutas e suas operações mais rápidas justamente por causa da garantia de tipo único.
  • Data frame: colunas de tipos diferentes - nomes ao lado de idades ao lado de sinalizadores lógicos. Isso é dado tabular do mundo real, e é o que quase todas as funções de análise de dados esperam.

Uma boa regra: se você abriria naturalmente aquilo em uma planilha com colunas nomeadas e mistas, é um data frame. Se é uma grade de números na qual você pretende fazer álgebra, é uma matriz. Converter entre eles é fácil (as.matrix(), as.data.frame()) - mas as.matrix() em um data frame com qualquer coluna de texto força tudo para caractere, então converta apenas as colunas numéricas.

O Que Você Leva Daqui

  • Uma matriz é um vetor com dimensões: um tipo do começo ao fim, construída com matrix(data, nrow, ncol) - e preenche coluna por coluna a menos que você passe byrow = TRUE.
  • Indexe como m[linha, coluna]; uma posição vazia significa "todas"; acrescente drop = FALSE ao fatiar linhas ou colunas únicas dentro de código.
  • cbind() e rbind() montam matrizes a partir de vetores ou estendem as existentes.
  • * é elemento a elemento, %*% é multiplicação de matrizes de verdade - mesmas entradas, respostas diferentes, nenhum aviso.
  • rowSums() / colSums() / rowMeans() / colMeans() dão conta dos resumos do dia a dia.

A seguir: fatores - como o R representa dados categóricos, e as armadilhas que vêm junto.

Perguntas frequentes

Como criar uma matriz no R?

matrix(1:6, nrow = 2) remodela um vetor em 2 linhas e 3 colunas, preenchendo coluna por coluna. Acrescente byrow = TRUE para preencher linha por linha. Você também pode montar uma matriz a partir de vetores: cbind() os cola como colunas, rbind() como linhas.

Qual é a diferença entre * e %*% no R?

* multiplica elemento a elemento - cada célula vezes a célula correspondente, e os formatos precisam bater. %*% é a verdadeira multiplicação de matrizes da álgebra linear (linhas vezes colunas, então as dimensões internas precisam coincidir). Eles dão resultados completamente diferentes nas mesmas matrizes, e usar * onde você queria %*% é um bug silencioso clássico.

Como pegar uma linha ou coluna de uma matriz no R?

Deixe a outra posição vazia: m[1, ] é a primeira linha, m[, 2] é a segunda coluna. Ambas voltam como vetores simples por padrão. Acrescente drop = FALSE - como em m[1, , drop = FALSE] - para manter o resultado como uma matriz de uma linha ou de uma coluna, o que importa quando o código seguinte espera duas dimensões.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR