Fundamentos de R

Minicurso de R · Módulo 0

R
fundamentos
vectores
matrices
Objetos, vectores, matrices, ayuda, paquetes y buenas prácticas de estilo para empezar a programar en R.
Author

Mauricio Romero

Published

September 25, 2026

Duración estimada: 1,5 horas · Nivel: principiante · Prerrequisitos: ninguno (solo tener R y RStudio instalados).

Objetivos de aprendizaje

Al terminar este cuaderno podrás:

  1. Usar R como calculadora y guardar resultados en objetos.
  2. Crear, indexar y operar vectores, incluyendo comparaciones lógicas y valores faltantes.
  3. Crear y manipular matrices (subconjuntos y aritmética).
  4. Buscar ayuda e instalar paquetes.
  5. Escribir código legible siguiendo una guía de estilo.
library(ggplot2)

1. R como calculadora

R evalúa expresiones y muestra el resultado. Los operadores aritméticos son +, -, *, /, ^ (potencia), %% (residuo) y %/% (división entera).

3 + 8
[1] 11
6 * 98
[1] 588
sqrt(200)
[1] 14.14214
17 %% 5      # residuo de 17 entre 5
[1] 2
17 %/% 5     # división entera
[1] 3
2^10
[1] 1024

Para guardar un resultado se usa el operador de asignación <- (atajo en RStudio: Alt + -):

radio <- 4
area <- pi * radio^2
area
[1] 50.26548
TipConsejo

En R, = también asigna, pero por convención se reserva <- para asignar objetos y = para pasar argumentos en las funciones. Así el código es más fácil de leer.

2. Teoría: los vectores son la base

En R casi todo es un vector: una colección ordenada de elementos del mismo tipo. Un número suelto es un vector de longitud 1. Los tipos atómicos más usados son:

Tipo class() Ejemplo
Numérico numeric 3.14, 81
Entero integer 5L
Texto character "alef"
Lógico logical TRUE, FALSE

Se crean con la función c() (de combine):

v_num  <- c(3, 9, 81)
v_text <- c("alef", "bet", "gimel")   # el texto siempre va entre comillas
v_bool <- c(TRUE, FALSE, TRUE)

class(v_num)
[1] "numeric"
class(v_text)
[1] "character"
class(v_bool)
[1] "logical"
length(v_num)
[1] 3

Si mezclas tipos, R los convierte al más general (coerción): lógico → numérico → texto.

c(1, TRUE, FALSE)      # lógico pasa a numérico
[1] 1 1 0
c(1, "a", TRUE)        # todo pasa a texto
[1] "1"    "a"    "TRUE"

Un vector puede tener nombres, lo que lo vuelve parecido a un diccionario:

prendas <- c(zapatos = "mocasines", gorra = "Yankees", camisa = "blanca")
prendas
    zapatos       gorra      camisa 
"mocasines"   "Yankees"    "blanca" 
names(prendas)
[1] "zapatos" "gorra"   "camisa" 
prendas["gorra"]
    gorra 
"Yankees" 

Operaciones vectorizadas

Las operaciones se aplican elemento a elemento, sin necesidad de bucles. Esta idea, llamada vectorización, es la que hace que R sea rápido y conciso:

x <- 1:10                # secuencia del 1 al 10
x * 2
 [1]  2  4  6  8 10 12 14 16 18 20
x^2
 [1]   1   4   9  16  25  36  49  64  81 100
sum(x); mean(x); sd(x)
[1] 55
[1] 5.5
[1] 3.02765
seq(0, 1, by = 0.25)
[1] 0.00 0.25 0.50 0.75 1.00
rep(c("a", "b"), times = 3)
[1] "a" "b" "a" "b" "a" "b"
x <- seq(0, 4 * pi, length.out = 200)
datos <- data.frame(x = x, seno = sin(x), amortiguada = exp(-x / 5) * sin(x))

ggplot(datos, aes(x)) +
  geom_line(aes(y = seno, colour = "sin(x)")) +
  geom_line(aes(y = amortiguada, colour = "exp(-x/5) sin(x)")) +
  scale_colour_manual(values = c("#e76f51", "#2a9d8f"), name = NULL) +
  labs(x = "x", y = "f(x)") +
  theme_minimal(base_size = 12)
Figure 1: Una sola línea de código vectorizado genera 200 puntos de una función. No hizo falta un bucle.

Indexación

Para extraer elementos se usan corchetes [ ] con tres opciones: posiciones, un vector lógico o nombres.

animales <- c("Elefante", "Jirafa", "Burro", "Caballo", "Cebra")

animales[2]            # una posición
[1] "Jirafa"
animales[c(1, 3)]      # varias posiciones
[1] "Elefante" "Burro"   
animales[-1]           # todo menos el primero
[1] "Jirafa"  "Burro"   "Caballo" "Cebra"  
animales[2:4]          # un rango
[1] "Jirafa"  "Burro"   "Caballo"
animales[nchar(animales) > 5]   # con una condición lógica
[1] "Elefante" "Jirafa"   "Caballo" 

3. Comparaciones y lógica

Las comparaciones (<, >, <=, >=, ==, !=) devuelven vectores lógicos. Se combinan con & (y), | (o) y ! (no).

edades <- c(12, 25, 37, 8, 64, 19)

edades > 18
[1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE
edades > 18 & edades < 40
[1] FALSE  TRUE  TRUE FALSE FALSE  TRUE
edades[edades > 18]
[1] 25 37 64 19
which(edades > 18)          # posiciones donde se cumple
[1] 2 3 5 6
any(edades > 60); all(edades > 5)
[1] TRUE
[1] TRUE
sum(edades > 18)            # TRUE cuenta como 1
[1] 4
WarningError frecuente

Para comparar igualdad se usa ==, no =. Además, con números decimales evita ==: 0.1 + 0.2 == 0.3 es FALSE por errores de redondeo. Usa isTRUE(all.equal(0.1 + 0.2, 0.3)).

Valores faltantes

Un dato ausente se representa con NA. Casi cualquier operación con NA da NA, así que hay que decirle a R cómo tratarlo:

temperatura <- c(21.5, 23.1, NA, 22.8, NA, 24.0)

mean(temperatura)                   # NA
[1] NA
mean(temperatura, na.rm = TRUE)     # ignora los faltantes
[1] 22.85
is.na(temperatura)
[1] FALSE FALSE  TRUE FALSE  TRUE FALSE
sum(is.na(temperatura))             # cuántos faltan
[1] 2

4. Matrices

Una matriz es un vector con dos dimensiones (filas y columnas) y elementos del mismo tipo.

M <- matrix(1:12, nrow = 3, ncol = 4)
M
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
M_fila <- matrix(1:12, nrow = 3, byrow = TRUE)   # se llena por filas
M_fila
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
dim(M); nrow(M); ncol(M)
[1] 3 4
[1] 3
[1] 4

Se pueden nombrar filas y columnas y luego indexar por posición o por nombre con [fila, columna]:

precipitacion <- matrix(c(120, 98, 45, 60, 150, 110, 70, 80, 130, 105, 55, 65),
                        nrow = 3, byrow = TRUE,
                        dimnames = list(estacion = c("Norte", "Centro", "Sur"),
                                        trimestre = c("T1", "T2", "T3", "T4")))
precipitacion
        trimestre
estacion  T1  T2 T3 T4
  Norte  120  98 45 60
  Centro 150 110 70 80
  Sur    130 105 55 65
precipitacion["Centro", "T2"]      # un valor
[1] 110
precipitacion["Sur", ]             # una fila completa
 T1  T2  T3  T4 
130 105  55  65 
precipitacion[, c("T1", "T4")]     # dos columnas
        trimestre
estacion  T1 T4
  Norte  120 60
  Centro 150 80
  Sur    130 65
precipitacion[precipitacion > 100] # valores mayores a 100
[1] 120 150 130 110 105

Las sumas y promedios por fila o columna se calculan con rowSums(), colMeans() y afines, o con apply():

rowSums(precipitacion)
 Norte Centro    Sur 
   323    410    355 
colMeans(precipitacion)
       T1        T2        T3        T4 
133.33333 104.33333  56.66667  68.33333 
apply(precipitacion, MARGIN = 1, FUN = max)   # máximo por fila
 Norte Centro    Sur 
   120    150    130 

Aritmética de matrices

Los operadores +, -, * actúan elemento a elemento. El producto matricial se escribe con %*%.

A <- matrix(c(2, 1, 1, 3), 2)
B <- matrix(c(1, 0, 4, 2), 2)

A * B          # elemento a elemento
     [,1] [,2]
[1,]    2    4
[2,]    0    6
A %*% B        # producto matricial
     [,1] [,2]
[1,]    2   10
[2,]    1   10
t(A)           # traspuesta
     [,1] [,2]
[1,]    2    1
[2,]    1    3
solve(A)       # inversa
     [,1] [,2]
[1,]  0.6 -0.2
[2,] -0.2  0.4
A %*% solve(A) # da la identidad
              [,1] [,2]
[1,]  1.000000e+00    0
[2,] -5.551115e-17    1
diag(2)        # matriz identidad
     [,1] [,2]
[1,]    1    0
[2,]    0    1
det(A)         # determinante
[1] 5

Un sistema de ecuaciones \(A\mathbf{x} = \mathbf{b}\) se resuelve con solve(A, b):

b <- c(5, 10)
solve(A, b)
[1] 1 3

5. Ayuda, paquetes y estilo

Cómo pedir ayuda

?mean                       # ayuda de una función
help("mean")                # equivalente
??"regresión"               # búsqueda por palabra clave
example(mean)               # ejecuta los ejemplos de la ayuda
vignette(package = "dplyr") # guías largas de un paquete

Cuando algo falle, copia el mensaje de error completo y búscalo en internet (ayuda de R, Stack Overflow o Posit Community).

Instalar y cargar paquetes

Un paquete se instala una sola vez con install.packages() y se carga en cada sesión con library():

install.packages("tidyverse")   # una vez por computador
library(tidyverse)              # en cada sesión
dplyr::filter(mtcars, cyl == 4) # usar una función sin cargar el paquete
WarningNunca dejes install.packages() dentro de un script compartido

Instalar paquetes en cada ejecución es lento y modifica el computador de quien lo corre. Documéntalos al inicio o usa renv para registrar las versiones de tu proyecto.

Guía de estilo

Un código legible se entiende meses después. Estas convenciones (basadas en la guía tidyverse) bastan para empezar:

Recomendado Evitar
datos_clima (minúsculas y guion bajo) DatosClima, datos.clima
x <- 5 x=5
mean(x, na.rm = TRUE) mean(x,na.rm=TRUE)
Líneas de menos de 80 caracteres Líneas larguísimas
Comentarios que explican el porqué Comentarios que repiten el código
Rutas relativas dentro de un proyecto setwd("C:/Users/yo/...")
set.seed() cuando se usa azar Resultados que cambian sin control

Sobre las rutas: crea un proyecto de RStudio (.Rproj) por cada análisis; así el directorio de trabajo es la carpeta del proyecto y el código funciona en cualquier computador. Evita también rm(list = ls()) al inicio de los scripts: no limpia todo (no reinicia los paquetes cargados) y borra el trabajo de quien lo ejecute. Mejor reinicia la sesión (Ctrl/Cmd + Shift + F10).

Ejercicios

  1. Vectores. Crea el vector edades <- c(12, 25, 37, 8, 64, 19). Calcula el promedio, selecciona las edades mayores que el promedio y cuenta cuántas son.
  2. Lógica. Dado x <- c(5, NA, 12, 7, NA, 3), calcula la media sin los faltantes y reemplaza los NA por esa media.
  3. Matrices. Construye una matriz de 3 × 3 con los números del 1 al 9 llenada por filas. Extrae la diagonal y calcula la suma de cada columna.
  4. Sistema lineal. Resuelve \(2x + y = 5\), \(x + 3y = 10\) con solve() y comprueba la solución multiplicando.
edades <- c(12, 25, 37, 8, 64, 19)
promedio <- mean(edades)
edades[edades > promedio]
[1] 37 64
sum(edades > promedio)
[1] 2
x <- c(5, NA, 12, 7, NA, 3)
x[is.na(x)] <- mean(x, na.rm = TRUE)
x
[1]  5.00  6.75 12.00  7.00  6.75  3.00
M3 <- matrix(1:9, 3, byrow = TRUE)
diag(M3)
[1] 1 5 9
colSums(M3)
[1] 12 15 18
A <- matrix(c(2, 1, 1, 3), 2, byrow = TRUE)
sol <- solve(A, c(5, 10))
sol
[1] 1 3
A %*% sol
     [,1]
[1,]    5
[2,]   10

Para profundizar

NoteReproducibilidad

Este cuaderno se ejecutó con R 4.5.2.