Menu

Vectores en R: c(), seq(), indexación y matemáticas vectorizadas

Los vectores son la unidad fundamental de R - incluso un solo número lo es. Cómo crearlos con c(), indexarlos (¡desde 1!), filtrarlos con máscaras lógicas y hacer cálculos sobre vectores enteros de una vez.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Todo en R es un vector

La mayoría de lenguajes tienen escalares - valores individuales - y luego algún tipo contenedor para guardar varios. R se salta el escalar. Un vector es una colección ordenada de valores que comparten un mismo tipo, y es la unidad sobre la que se construye todo lo demás. Incluso lo que parece un número solitario es un vector de longitud 1:

c() - abreviatura de combine - es como construyes un vector a mano. length() te dice cuántos elementos contiene. Y 5 por sí solo informa de is.vector como TRUE con longitud 1: R nunca deja de trabajar con vectores, solo que a veces trabaja con unos muy cortos.

Este diseño es la razón por la que el código de R se ve distinto del de Python o JavaScript: operaciones para las que en otros sitios escribirías un bucle se aplican a vectores enteros en una sola expresión. Llegaremos a eso más abajo.

Una regla que interiorizar ya: todos los elementos de un vector son del mismo tipo. Si le pasas a c() una mezcla, no se queja - convierte en silencio todo al tipo más flexible presente:

Una cadena en la mezcla convierte todo en cadenas ("1", "TRUE"). Los lógicos entre números se vuelven 1 y 0. Esta coerción sigue un orden jerárquico fijo - logical → integer → double → character - y ocurre sin aviso, y por eso un "7" despistado en una columna de números puede convertir discretamente todo tu conjunto de datos en texto. La jerarquía completa se cubre en tipos de datos; si necesitas guardar valores genuinamente mezclados, para eso están las listas.

Generar secuencias: :, seq() y rep()

Escribir cada elemento dentro de c() cansa rápido. R tiene tres atajos para patrones regulares:

  • 1:10 es el del día a día: enteros de un extremo al otro, en pasos de 1.
  • seq() lo generaliza: elige el paso con by =, o di cuántos elementos quieres con length.out = y deja que R calcule el espaciado.
  • seq_len(n) produce del 1 al n y es la forma segura de construir índices de bucle - a diferencia de 1:n, devuelve correctamente un vector vacío cuando n es 0 en lugar de contar 1 0 hacia atrás.
  • rep() repite: times = repite el vector entero de principio a fin (1 2 1 2 1 2), each = repite cada elemento en su sitio (1 1 1 2 2 2). Es fácil confundirlos; ejecuta el fragmento y compara.

Indexación: R cuenta desde 1

Los corchetes extraen elementos. El primer elemento es [1] - no [0]. Si vienes de Python o JavaScript, este es el tropiezo temprano más común:

Tres cosas aquí merecen una pausa:

  • Puedes indexar con un vector de posiciones - fruits[c(2, 4)] toma el segundo y el cuarto de una vez.
  • Los índices negativos significan "todo excepto". fruits[-1] es el vector sin su primer elemento. Esto es completamente distinto de Python, donde -1 significa el último elemento. No puedes mezclar índices positivos y negativos en la misma llamada.
  • fruits[0] no es un error - devuelve un character(0) vacío. Un error de desplazamiento en uno en R suele producir resultados vacíos silenciosos en lugar de una caída, así que compensa comprobar length() cuando algo más adelante aparece misteriosamente en blanco.

Los elementos también pueden llevar nombres, lo que te da una tercera forma de indexar - por etiqueta:

Los vectores con nombres funcionan como una tabla de consulta ligera y mantienen el código legible: prices["tea"] dice lo que significa, prices[2] no.

Máscaras lógicas y which()

La forma más potente de indexar es con un vector lógico - una máscara de valores TRUE/FALSE de la misma longitud que los datos. Toda comparación sobre un vector produce exactamente eso:

temps > 24 no da una respuesta - da cinco, una por elemento. Poner esa máscara dentro de [ ] conserva los elementos donde la máscara es TRUE. Combina condiciones con & (y) y | (o), cubiertos junto al resto de los operadores.

which() traduce una máscara a posiciones: aquí 2 3 5, los índices de las lecturas calurosas. Recurre a él cuando necesites saber dónde están las coincidencias - para informar de ellas o para indexar otro vector en esos mismos puntos. Para filtrar sin más, temps[temps > 24] es más directo que temps[which(temps > 24)].

Este patrón de filtrar con una máscara es la columna vertebral de prácticamente todo el trabajo con datos en R - vuelve tal cual cuando filtras filas de un data frame.

Matemáticas vectorizadas y la regla de reciclaje

La aritmética en R se aplica elemento a elemento sobre vectores enteros - sin necesidad de bucles:

La primera línea es la característica estrella: prices * 2 duplica cada elemento. Donde otros lenguajes necesitan un bucle for, R necesita un operador - y la forma vectorizada es a la vez más corta y más rápida, porque la iteración ocurre en C optimizado por debajo. Escribe un bucle for cuando cada paso dependa del anterior; para cálculos elemento a elemento, vectoriza.

La tercera línea muestra la regla de reciclaje: cuando los vectores tienen longitudes distintas, R repite el más corto para igualar. c(10, 20) se recicla a 10 20 10 20, dando 11 22 13 24. Reciclar el 2 sobre un vector de longitud 3 es exactamente lo que hizo funcionar a prices * 2 - un escalar no es más que un vector de longitud 1 que se recicla.

El reciclaje es limpio cuando la longitud mayor es un múltiplo exacto de la menor. Cuando no lo es, R sigue calculando una respuesta - y emite un aviso:

Obtienes 11 22 13 más un aviso de que la longitud del objeto más largo no es múltiplo de la del más corto. Trata ese aviso como un informe de bug: el reciclaje parcial casi nunca es lo que querías decir, y suele significar que dos vectores que deberían tener la misma longitud no la tienen.

Ordenar, invertir, eliminar duplicados

Tres pequeñas utilidades que usarás constantemente:

sort() ordena los valores, rev() da la vuelta al orden existente sin ordenar y unique() elimina los duplicados conservando las primeras apariciones. Ninguna modifica x - como casi todo en R, devuelven un vector nuevo y dejan el original en paz.

Lo que te llevas

  • Un vector es la unidad fundamental de R: ordenado, de un solo tipo en todo su recorrido, y hasta los valores individuales son vectores de longitud 1.
  • Constrúyelos con c(), genera patrones con :, seq() y rep() - y recuerda que c() coacciona los tipos mezclados en silencio.
  • La indexación empieza en 1; los índices negativos eliminan elementos; los nombres te dejan indexar por etiqueta.
  • Las máscaras lógicas (x[x > 5]) son el modismo de filtrado de todo el lenguaje; which() convierte una máscara en posiciones.
  • Los cálculos están vectorizados, los vectores más cortos se reciclan y un aviso de reciclaje parcial significa que tienes un bug.

Lo siguiente: las listas - el contenedor para cuando tus valores no comparten todos un mismo tipo.

Preguntas frecuentes

¿Cómo se crea un vector en R?

Con la función c() (de combine): x <- c(10, 20, 30). Para secuencias regulares, usa 1:10, seq(0, 1, by = 0.25) o rep(0, 5). Todos los elementos deben acabar siendo del mismo tipo - si mezclas tipos, R los convierte todos en silencio al más flexible.

¿La indexación en R empieza en 0 o en 1?

En 1. x[1] es el primer elemento y x[length(x)] el último. Esto hace tropezar a todo el que llega de Python, JavaScript o C - no existe el elemento x[0] (pedirlo devuelve un vector vacío, no un error, lo que hace que el bug sea silencioso).

¿Qué hace la regla de reciclaje en R?

Cuando haces aritmética con dos vectores de longitudes distintas, R repite el más corto hasta igualar al más largo. c(1, 2, 3, 4) + c(10, 20) da 11 22 13 24. Si la longitud mayor no es múltiplo de la menor, R sigue calculando una respuesta pero emite un aviso - trata ese aviso como un bug.

¿Qué hace which() en R?

Convierte un vector lógico en las posiciones de sus valores TRUE. Si x > 5 da FALSE TRUE TRUE, entonces which(x > 5) da 2 3. Úsalo cuando necesites las posiciones en sí; para filtrar sin más, indexar directamente con el vector lógico (x[x > 5]) es más sencillo.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR