Una matriz es un vector con dimensiones
Una matriz en R es un rectángulo de valores - filas y columnas - donde cada celda guarda el mismo tipo, normalmente números. Por dentro es literalmente un vector con un atributo dim grapado encima, lo que explica la mayor parte de su comportamiento: un solo tipo en todo, cálculos vectorizados en todas partes.
Construyes una reorganizando un vector con matrix():
Seis valores, dos filas - R deduce que hacen falta tres columnas. dim() informa de ambas dimensiones a la vez como 2 3; nrow() y ncol() las dan por separado.
Fíjate bien en la matriz impresa: los valores van 1 2 bajando por la primera columna y luego 3 4 por la siguiente. R rellena las matrices columna a columna por defecto. Si tus datos se leen fila a fila - que es como suelen escribirlos las personas -, dilo con byrow = TRUE:
Ahora la primera fila es 1 2 3. Olvidar byrow = TRUE no da error - te da en silencio una disposición con aspecto de transpuesta de los mismos números, así que acostúmbrate a comprobar la distribución impresa siempre que construyas una matriz a partir de valores en bruto.
Indexación: m[fila, columna]
La indexación de matrices toma dos posiciones dentro de un mismo par de corchetes, la fila antes de la coma y la columna después - ambas contando desde 1:
Dejar una posición vacía significa "todas": m[1, ] es toda la primera fila y m[, 2] toda la segunda columna. Fíjate en que ambas vuelven como vectores normales - R elimina la dimensión que se colapsó a tamaño 1. Eso es cómodo de forma interactiva y una trampa en el código, porque una función que espera una matriz se atragantará con el vector. Pídele a R que conserve la forma con drop = FALSE:
dim() ahora informa de 1 3 - sigue siendo una matriz. Siempre que extraigas una sola fila o columna dentro de una función, escribe drop = FALSE; el bug que evita (código que funciona con datos anchos y se rompe con datos de una columna) es de los más miserables de rastrear.
Las máscaras lógicas también funcionan aquí: m[m > 3] devuelve todas las celdas por encima de 3, como un vector.
Construir con cbind() y rbind()
En lugar de reorganizar un vector largo, puedes ensamblar una matriz a partir de piezas: cbind() une vectores como columnas y rbind() como filas. Las mismas funciones también amplían una matriz existente:
Los nombres viajan con los vectores: cbind() usó heights y weights como nombres de columna automáticamente, lo que mantiene legible la matriz impresa. Ambas funciones insisten en que las longitudes encajen (con reciclaje para valores de longitud 1); unir un vector de longitud 3 a una matriz de 4 filas te avisa.
Los nombres de columnas y filas también se pueden fijar directamente con colnames(m) <- ... y rownames(m) <- ..., tras lo cual puedes indexar por nombre: people[, "weights"].
El * elemento a elemento frente a la verdadera multiplicación matricial %*%
Aquí está la distinción que más importa de todo este artículo. R tiene dos operadores de multiplicación para matrices, y calculan cosas totalmente distintas:
a * aes elemento a elemento: cada celda multiplicada por la celda correspondiente.1 2 3 4se convierten en1 4 9 16, dispuestos con la misma forma. Esto no es más que aritmética vectorizada, el mismo*que usas con vectores.a %*% aes la multiplicación de matrices del álgebra lineal - cada celda del resultado es una fila de la primera matriz por una columna de la segunda, sumadas. La misma entrada da7 10 15 22: números completamente diferentes.
Ejecuta el fragmento y compara las dos salidas una al lado de la otra; ver cómo difieren con entradas idénticas es lo que hace que la distinción se quede. Si escribes * donde el cálculo pide %*%, R no te avisará - las formas son compatibles en ambos casos para matrices cuadradas - simplemente obtendrás números incorrectos. En código de estadística (matrices de covarianza, álgebra de modelos lineales) este es uno de los bugs silenciosos clásicos.
t() transpone - intercambia filas y columnas - y aparece constantemente junto a %*% porque la multiplicación de matrices necesita que las dimensiones interiores coincidan:
Para completar: solve(m) invierte una matriz, y %*% con un vector lo trata como una matriz de una columna. Eso es lo más lejos que necesita llegar la mayoría del trabajo con datos.
Resúmenes por filas y columnas
Sumar o promediar por filas y columnas es tan habitual que R incluye funciones dedicadas y rápidas para ello:
rowSums() colapsa cada fila a un número (6 15 aquí), colSums() cada columna (5 7 9), y las variantes Means promedian en lugar de sumar. Prefiérelas frente a bucles caseros o incluso a apply(m, 1, sum) - son más claras y más rápidas. Para resúmenes que estas cuatro no cubren (digamos, el máximo por columna), la familia apply es la herramienta general: apply(m, 2, max).
¿Matriz o data frame?
Ambos son rectangulares, así que ¿a cuál recurres?
- Matriz: todas las celdas del mismo tipo y las matemáticas importan. Cálculo numérico, álgebra lineal, cálculos de distancias, rejillas tipo imagen. Las matrices son más ligeras y sus operaciones más rápidas precisamente por la garantía de un único tipo.
- Data frame: columnas de tipos diferentes - nombres junto a edades junto a indicadores lógicos. Estos son los datos tabulares del mundo real, y es lo que esperan casi todas las funciones de análisis de datos.
Una buena regla: si lo abrirías de forma natural en una hoja de cálculo con columnas nombradas y mezcladas, es un data frame. Si es una rejilla de números sobre la que piensas hacer álgebra, es una matriz. Convertir entre ambos es fácil (as.matrix(), as.data.frame()) - pero as.matrix() sobre un data frame con alguna columna de texto coacciona todo a carácter, así que convierte solo las columnas numéricas.
Lo que te llevas
- Una matriz es un vector con dimensiones: un solo tipo en todo, construida con
matrix(data, nrow, ncol)- y se rellena columna a columna salvo que pasesbyrow = TRUE. - Indexa como
m[fila, columna]; una posición vacía significa "todas"; añadedrop = FALSEal extraer filas o columnas sueltas dentro del código. cbind()yrbind()ensamblan matrices a partir de vectores o amplían las existentes.*es elemento a elemento,%*%es la multiplicación matricial real - mismas entradas, respuestas distintas, ningún aviso.rowSums()/colSums()/rowMeans()/colMeans()cubren los resúmenes del día a día.
Lo siguiente: los factores - cómo representa R los datos categóricos, y las trampas que traen consigo.
Preguntas frecuentes
¿Cómo se crea una matriz en R?
matrix(1:6, nrow = 2) reorganiza un vector en 2 filas y 3 columnas, rellenando columna a columna. Añade byrow = TRUE para rellenar fila a fila. También puedes ensamblar una matriz a partir de vectores: cbind() los pega como columnas y rbind() como filas.
¿Cuál es la diferencia entre * y %*% en R?
* multiplica elemento a elemento - cada celda por la celda correspondiente, y las formas deben encajar. %*% es la verdadera multiplicación de matrices del álgebra lineal (filas por columnas, así que las dimensiones interiores deben coincidir). Dan resultados completamente distintos sobre las mismas matrices, y usar * donde querías decir %*% es un bug silencioso clásico.
¿Cómo se obtiene una fila o una columna de una matriz en R?
Deja vacía la otra posición: m[1, ] es la primera fila y m[, 2] la segunda columna. Ambas vuelven como vectores normales por defecto. Añade drop = FALSE - como en m[1, , drop = FALSE] - para conservar el resultado como una matriz de una fila o una columna, lo que importa cuando el código posterior espera dos dimensiones.