Vectores: el modelo mental que sostiene todo R
En R no existen los escalares: todo es un vector. Entender esa idea — crear, indexar, vectorizar y esquivar el reciclaje silencioso — es entender el lenguaje.
1. En R no existen los escalares
¿Alguna vez te preguntaste por qué R imprime [1] 5 cuando escribes 5? Ese [1] es la pista de la idea más importante del lenguaje: en R no existen los números sueltos. Cuando escribes 5, R lo trata como un vector numérico de longitud 1, y el [1] te dice 'este es el elemento en la posición 1'. Toda función de R está diseñada pensando en vectores, y eso explica por qué el lenguaje se siente tan natural para análisis de datos: una columna de ventas, una serie de precios o las respuestas de una encuesta SON vectores. Todo lo demás — matrices, factores, data frames — se construye sobre ellos. Cada filtro que escribas será una condición sobre un vector; cada función de resumen (mean(), sum(), max()) recibe un vector. Dominar esta estructura no es aprender 'una más': es aprender el idioma nativo.
2. Crear vectores: c(), secuencias y repeticiones
La función c() (de combine) es la más usada de todo R, pero para secuencias regulares hay herramientas más expresivas. Cada creador tiene su especialidad: c() combina valores sueltos (y concatena vectores enteros), el operador : es el atajo para secuencias enteras de paso 1, seq() te deja controlar el paso (by) o el número de elementos (length.out), y rep() repite — con dos argumentos que la gente confunde: times repite el bloque completo, each repite cada elemento antes de pasar al siguiente. ¿Dónde se usa esto en la vida real? Etiquetas de periodos, grupos de un experimento, rejillas de escenarios, ejes de gráficos:
ventas <- c(150, 172, 168, 195) # c() = combinar valores
seq(0, 1, by = 0.25) # controlas el paso
# [1] 0.00 0.25 0.50 0.75 1.00
seq(0, 100, length.out = 5) # controlas cuántos elementos
# [1] 0 25 50 75 100
rep(c("T1", "T2"), times = 3) # el bloque entero, 3 veces
# [1] "T1" "T2" "T1" "T2" "T1" "T2"
rep(c("T1", "T2"), each = 3) # cada elemento, 3 veces seguidas
# [1] "T1" "T1" "T1" "T2" "T2" "T2"3. Las 5 formas de indexar (¡empieza en 1!)
Indexar es pedirle al vector un subconjunto con corchetes, y dominar las cinco formas paga doble: son exactamente las mismas que luego usarás con matrices y data frames. Posición positiva (dame el elemento 1), negativa (todo MENOS el 1), condición lógica (los que cumplen), por nombre, y which() — que no devuelve los valores sino sus posiciones. La condición lógica merece pausa: ventas > 165 produce FALSE TRUE TRUE TRUE, y al meterlo en los corchetes R conserva solo los TRUE; ese patrón es el corazón de todo filtro que harás en tu vida con R. Y una advertencia que evita bugs silenciosos: en R los índices empiezan en 1, no en 0 — v[0] no da error, devuelve un vector vacío, que es peor porque pasa desapercibido. Bonus: los corchetes también escriben — asignarles un valor reemplaza exactamente esas posiciones, el patrón estándar de la limpieza de datos:
ventas <- c(ene = 150, feb = 172, mar = 168, abr = 195)
ventas[c(2, 4)] # por posición: feb abr → 172 195
ventas[-1] # todo menos la 1: feb mar abr
ventas[ventas > 165] # condición lógica: feb mar abr
ventas["mar"] # por nombre: mar → 168
which(ventas > 165) # ¿en qué POSICIONES? 2 3 4
# Los corchetes también escriben:
ventas["mar"] <- 170 # corregir un dato puntual
ventas[ventas < 160] <- NA # marcar sospechosos de un golpe
ventas
# ene feb mar abr
# NA 172 170 1954. Vectorización: el superpoder
En la mayoría de lenguajes, para aplicar el IVA a 4 precios escribirías un bucle. En R, las operaciones actúan sobre todo el vector a la vez — y el 'bucle' ocurre internamente en código C compilado, por eso es más corto, más legible y más rápido. Cuando pienses 'necesito hacer X a cada elemento', tu primer reflejo no debe ser un bucle sino preguntarte si la operación ya es vectorizada: casi siempre lo es (+, *, sqrt(), round(), comparaciones, paste()...). Y la vectorización también opera entre DOS vectores, emparejando posición con posición — exactamente lo que harás entre columnas de una tabla. Mira cómo dos miradas al mismo dato cuentan historias distintas: el segundo producto deja el mayor margen absoluto, pero el tercero tiene el mejor margen relativo:
precios <- c(100, 250, 80, 120)
con_iva <- precios * 1.19 # una línea, sin índices, sin bucle
# [1] 119.0 297.5 95.2 142.8
costos <- c(80, 190, 60, 95)
margen <- precios - costos # entre dos vectores, par a par
# [1] 20 60 20 25
round(margen / precios * 100, 1) # margen % de cada producto
# [1] 20.0 24.0 25.0 20.85. Reciclaje: la regla y el peligro
¿Qué pasa si operas dos vectores de distinta longitud? R recicla el más corto: lo repite hasta alcanzar al largo. Es lo que hace que precios * 1.19 funcione (el 1.19 se recicla 4 veces). La regla: si la longitud mayor es múltiplo exacto de la menor, R recicla en silencio; si no, recicla igual pero advierte. Y ahí está la trampa: el peligro real no es la advertencia, sino el caso donde NO hay advertencia. Si sumas por accidente un vector de 12 meses con uno de 4 trimestres, las longitudes encajan (12 es múltiplo de 4), R no dice nada, y obtienes números plausibles pero incorrectos. Ante resultados sospechosos, lo primero: verificar longitudes con length():
c(1, 2, 3, 4) + c(10, 20) # 4 es múltiplo de 2: recicla SIN avisar
# [1] 11 22 13 24
c(1, 2, 3) + c(10, 20) # 3 no es múltiplo de 2: recicla Y advierte
# [1] 11 22 13
# Warning: longer object length is not a multiple of shorter object length6. Los modismos del analista
Cierro con el ejemplo que junta todo: seis meses de ventas (en millones) y cinco preguntas de negocio respondidas en cinco líneas. Fíjate en dos modismos que usan todos los analistas de R: mean() de un vector lógico da la PROPORCIÓN de casos que cumplen (porque TRUE vale 1), y sum() de un lógico los CUENTA. Y un detalle fino en el crecimiento porcentual: la base es ventas[-6] (todos menos junio, porque el último mes no es base de nadie) — emparejar bien numerador y base es la diferencia entre un crecimiento correcto y uno desfasado un mes:
ventas <- c(ene = 150, feb = 172, mar = 168, abr = 195, may = 210, jun = 250)
cumsum(ventas) # acumulado: cierra el semestre en 1145
diff(ventas) # variación mensual: solo marzo cayó (-4)
# feb mar abr may jun
# 22 -4 27 15 40
round(diff(ventas) / ventas[-6] * 100, 1) # crecimiento % mes a mes
# feb mar abr may jun
# 14.7 -2.3 16.1 7.7 19.0
names(ventas)[which.max(ventas)] # el mejor mes → "jun"
mean(ventas > 180) # proporción sobre la meta → 0.5- 01R básico: aprende R desde cero
- 02RStudio como un profesional
- 03Vectores: el modelo mental que sostiene todo REstás aquí
- 04Tipos de datos y coerción: por qué 0.1 + 0.2 != 0.3Próximamente
- 05Factores: la trampa de as.numeric()Próximamente
- 06Listas: [ vs [[ vs $ (y por qué un modelo es una lista)Próximamente
- 07Importar datos en Latinoamérica: punto y coma, coma decimal y tildesPróximamente
- 08Transformar datos con dplyr y tidyrPróximamente
- 09Funciones propias y tryCatch: pipelines que no se caenPróximamente
- 10data.table vs. dplyr: cuándo usar cada unoPróximamente
- 11Tu checklist de EDA reutilizablePróximamente
- 12Quarto y Git: publicar un análisis reproduciblePróximamente
También te puede interesar
R básico: aprende R desde cero, sin haber programado nunca
Guía de R para principiantes absolutos, en 12 pasos: qué es R y por qué aprenderlo, instalación verificada, tu primer script, objetos, tipos de datos, vectores, factores, data frames, el tidyverse, importación de datos y tu primer gráfico con ggplot2. Con errores comunes y recursos oficiales gratuitos para seguir.
RStudio como un profesional: script, proyecto y flujo de trabajo
Tutorial del flujo de trabajo profesional en RStudio: el mapa de los cuatro paneles, el circuito Source → Console → Environment, la regla 'la consola prueba, el script es la verdad', proyectos .Rproj con rutas relativas, la configuración anti-.RData y los atajos que pagan cada día.
Observatorio GEIH: cómo servir 4 años de microdatos del DANE en una app que carga al instante
La historia técnica del Observatorio GEIH (2022–2025): pre-agregación offline respetando la metodología DANE, app Shiny modular de 7 dimensiones, auditoría automatizada contra el microdato y publicación en Springer (CCIS, R Day 2025).