¿Por qué aprender R?

R es el lenguaje estándar en economía, estadística y ciencias sociales para analizar datos.

Con R podrás:

  • Limpiar y transformar bases de datos (encuestas, registros administrativos, datos del INEGI)
  • Calcular estadísticas descriptivas y hacer pruebas de hipótesis
  • Crear gráficas publicables para tesis, reportes y artículos
  • Automatizar análisis que en Excel tomarían horas

A diferencia de Excel, R guarda un registro exacto de cada paso que hiciste con tus datos, lo que hace tu trabajo reproducible y verificable. —

Parte 1 — Operaciones básicas

R puede usarse directamente como calculadora. Corre cada línea en la consola y observa el resultado.

1 + 1
#> [1] 2
10 - 3
#> [1] 7
4 * 5
#> [1] 20
20 / 4
#> [1] 5
2 ^ 8      # Potencia: 2 elevado a la 8
#> [1] 256
17 %% 5    # Módulo: residuo de dividir 17 entre 5
#> [1] 2

El operador de asignación <-

En R guardamos resultados en objetos usando <-.

mi_suma <- 1 + 1
mi_suma            # escribir el nombre lo imprime en consola
#> [1] 2
print(mi_suma)     # print() hace lo mismo de forma explícita
#> [1] 2

Convención: en R usamos <- para asignar, no =. El signo = también funciona, pero <- es el estándar de la comunidad R.


Parte 2 — Tipos de objetos en R

En R todo lo que creamos es un objeto. Cada objeto tiene un tipo (class) que determina qué operaciones podemos hacer con él.

Usamos class() para saber el tipo y str() para ver su estructura.


Tipo 1: numeric — número decimal

El tipo numérico más común. Se usa para medidas continuas: pesos, temperaturas, distancias, precios.

estatura <- 1.64   # metros
peso     <- 67     # kilogramos
imc      <- peso / (estatura ^ 2)
imc                # Índice de Masa Corporal
#> [1] 24.91077
class(imc)         # "numeric"
#> [1] "numeric"
str(imc)           # num 22.5
#>  num 24.9

Tipo 2: integer — número entero

Se usa cuando los valores no tienen decimales. Se escribe con L al final.

edad    <- 25L
alumnos <- 30L
semanas <- 16L

class(edad)        # "integer"
#> [1] "integer"
str(edad)          # int 25
#>  int 25

¿Cuál es la diferencia práctica entre numeric e integer?

x_num <- 5    # R lo guarda como decimal: 5.0
x_int <- 5L   # R lo guarda como entero:  5

class(x_num)      # "numeric"
#> [1] "numeric"
class(x_int)      # "integer"
#> [1] "integer"
is.integer(x_num) # FALSE
#> [1] FALSE
is.integer(x_int) # TRUE
#> [1] TRUE

En la mayoría de los cálculos se comportan igual, pero integer ocupa menos memoria (útil cuando trabajas con millones de filas).


Tipo 3: character — texto

Se usa para guardar palabras u oraciones. Siempre va entre comillas " " o ' '.

nombre_est <- "Araceli"
ciudad     <- "Ciudad de México"
carrera    <- "Economía"

class(nombre_est)  # "character"
#> [1] "character"

Funciones útiles con texto

# paste() une cadenas con un espacio entre cada pieza
presentacion <- paste("Hola, me llamo", nombre_est,
                      "y estudio", carrera, "en", ciudad)
print(presentacion)
#> [1] "Hola, me llamo Araceli y estudio Economía en Ciudad de México"
# paste0() une sin espacios (útil para nombres de archivos)
archivo <- paste0("reporte_", nombre_est, "_2026.csv")
print(archivo)
#> [1] "reporte_Araceli_2026.csv"
# Otras funciones
nchar(presentacion)      # Total de caracteres
#> [1] 61
toupper(nombre_est)      # MAYÚSCULAS
#> [1] "ARACELI"
tolower(ciudad)          # minúsculas
#> [1] "ciudad de méxico"
substr(carrera, 1, 3)    # Primeras 3 letras: "Eco"
#> [1] "Eco"

Tipo 4: logical — verdadero o falso

Solo tiene dos valores posibles: TRUE o FALSE. Es el resultado de cualquier comparación.

aprobado  <- TRUE
reprobado <- FALSE

class(aprobado)    # "logical"
#> [1] "logical"

Operadores de comparación

10 > 5             # ¿10 mayor que 5?       TRUE
#> [1] TRUE
10 < 5             # ¿10 menor que 5?       FALSE
#> [1] FALSE
10 == 10           # ¿10 igual a 10?        TRUE  (doble ==)
#> [1] TRUE
10 != 5            # ¿10 diferente de 5?    TRUE
#> [1] TRUE
10 >= 10           # ¿10 mayor o igual a 10?TRUE
#> [1] TRUE
10 <= 9            # ¿10 menor o igual a 9? FALSE
#> [1] FALSE
calificacion <- 85
calificacion >= 60  # ¿Aprobó?  -> TRUE
#> [1] TRUE
calificacion >= 90  # ¿Sacó A?  -> FALSE
#> [1] FALSE

Truco útil: TRUE vale 1 y FALSE vale 0 en cálculos numéricos.

sum(TRUE, TRUE, FALSE, TRUE)                    # 3 "verdaderos"
#> [1] 3
mean(c(TRUE, FALSE, TRUE, TRUE, FALSE))         # 0.6 = 60% son TRUE
#> [1] 0.6

Tipo 5: vector — múltiples valores del mismo tipo

Un vector guarda varios valores en una sola variable con c() (combine). Todos los elementos deben ser del mismo tipo.

# Vector de caracteres
palabras <- c("Me", "gusta", "mi", "clase", "de", "R")
str(palabras)       # chr [1:6]
#>  chr [1:6] "Me" "gusta" "mi" "clase" "de" "R"
length(palabras)    # 6 elementos
#> [1] 6
# Vector numérico
calificaciones <- c(78, 85, 92, 67, 90, 88)
mean(calificaciones)  # Promedio: 83.3
#> [1] 83.33333
max(calificaciones)   # Máximo:   92
#> [1] 92
min(calificaciones)   # Mínimo:   67
#> [1] 67
range(calificaciones) # Rango:    67 92
#> [1] 67 92

Acceder a elementos por posición

Importante: en R los índices empiezan en 1, no en 0 como en Python.

calificaciones[1]    # Primer elemento:  78
#> [1] 78
calificaciones[3]    # Tercer elemento:  92
#> [1] 92
calificaciones[2:4]  # Del segundo al cuarto: 85 92 67
#> [1] 85 92 67

Secuencias rápidas con :

dias <- 1L:7L
str(dias)    # int [1:7] 1 2 3 4 5 6 7
#>  int [1:7] 1 2 3 4 5 6 7
print(dias)
#> [1] 1 2 3 4 5 6 7

Tipo 6: factor — variable categórica

Un factor es como un character pero con categorías fijas llamadas levels. Es ideal para variables como nivel educativo, región, género o carrera.

nivel_edu <- factor(c("Licenciatura", "Maestria", "Doctorado",
                      "Licenciatura", "Maestria", "Maestria"))
print(nivel_edu)
#> [1] Licenciatura Maestria     Doctorado    Licenciatura Maestria    
#> [6] Maestria    
#> Levels: Doctorado Licenciatura Maestria
levels(nivel_edu)   # Categorías disponibles
#> [1] "Doctorado"    "Licenciatura" "Maestria"
table(nivel_edu)    # Frecuencia de cada categoría
#> nivel_edu
#>    Doctorado Licenciatura     Maestria 
#>            1            2            3

Factor ordenado (variable ordinal)

Cuando las categorías tienen jerarquía, usamos ordered = TRUE:

satisfaccion <- factor(
  c("Alto", "Medio", "Bajo", "Alto", "Bajo"),
  levels  = c("Bajo", "Medio", "Alto"),
  ordered = TRUE
)
print(satisfaccion)
#> [1] Alto  Medio Bajo  Alto  Bajo 
#> Levels: Bajo < Medio < Alto
satisfaccion[1] > satisfaccion[3]   # ¿Alto > Bajo? -> TRUE
#> [1] TRUE

Tipo 7: data.frame — tabla de datos

El objeto más usado en análisis de datos. Piénsalo como una hoja de Excel: filas = observaciones, columnas = variables. Cada columna puede ser de un tipo diferente.

estudiantes <- data.frame(
  nombre       = c("Ana", "Luis", "Maria", "Carlos", "Sofia", "Pedro"),
  edad         = c(22L, 25L, 21L, 23L, 20L, 24L),
  calificacion = c(90.5, 58.0, 95.3, 82.1, 47.6, 76.4),
  carrera      = factor(c("Economia", "Derecho", "Economia",
                          "Derecho", "Economia", "Derecho")),
  aprobado     = c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE)
)

print(estudiantes)
#>   nombre edad calificacion  carrera aprobado
#> 1    Ana   22         90.5 Economia     TRUE
#> 2   Luis   25         58.0  Derecho    FALSE
#> 3  Maria   21         95.3 Economia     TRUE
#> 4 Carlos   23         82.1  Derecho     TRUE
#> 5  Sofia   20         47.6 Economia    FALSE
#> 6  Pedro   24         76.4  Derecho     TRUE

Explorar la estructura

str(estudiantes)       # Tipo de cada columna
#> 'data.frame':    6 obs. of  5 variables:
#>  $ nombre      : chr  "Ana" "Luis" "Maria" "Carlos" ...
#>  $ edad        : int  22 25 21 23 20 24
#>  $ calificacion: num  90.5 58 95.3 82.1 47.6 76.4
#>  $ carrera     : Factor w/ 2 levels "Derecho","Economia": 2 1 2 1 2 1
#>  $ aprobado    : logi  TRUE FALSE TRUE TRUE FALSE TRUE
nrow(estudiantes)      # Número de filas
#> [1] 6
ncol(estudiantes)      # Número de columnas
#> [1] 5
dim(estudiantes)       # Dimensiones: 6 x 5
#> [1] 6 5
summary(estudiantes)   # Resumen estadístico
#>     nombre               edad        calificacion       carrera 
#>  Length:6           Min.   :20.00   Min.   :47.60   Derecho :3  
#>  Class :character   1st Qu.:21.25   1st Qu.:62.60   Economia:3  
#>  Mode  :character   Median :22.50   Median :79.25               
#>                     Mean   :22.50   Mean   :74.98               
#>                     3rd Qu.:23.75   3rd Qu.:88.40               
#>                     Max.   :25.00   Max.   :95.30               
#>   aprobado      
#>  Mode :logical  
#>  FALSE:2        
#>  TRUE :4        
#>                 
#>                 
#> 

Acceder a columnas con $

estudiantes$nombre
#> [1] "Ana"    "Luis"   "Maria"  "Carlos" "Sofia"  "Pedro"
estudiantes$calificacion
#> [1] 90.5 58.0 95.3 82.1 47.6 76.4
mean(estudiantes$calificacion)  # Promedio general
#> [1] 74.98333
max(estudiantes$calificacion)   # Calificación más alta
#> [1] 95.3

Filtrar filas

# Solo estudiantes aprobados
estudiantes[estudiantes$aprobado == TRUE, ]
# Solo estudiantes de Economía
estudiantes[estudiantes$carrera == "Economia", ]

Agregar una nueva columna

estudiantes$beca <- estudiantes$calificacion >= 85
print(estudiantes)
#>   nombre edad calificacion  carrera aprobado  beca
#> 1    Ana   22         90.5 Economia     TRUE  TRUE
#> 2   Luis   25         58.0  Derecho    FALSE FALSE
#> 3  Maria   21         95.3 Economia     TRUE  TRUE
#> 4 Carlos   23         82.1  Derecho     TRUE FALSE
#> 5  Sofia   20         47.6 Economia    FALSE FALSE
#> 6  Pedro   24         76.4  Derecho     TRUE FALSE

Parte 3 — Errores comunes y cómo evitarlos

Estos son los errores que casi todos los principiantes cometen. Léelos con atención para ahorrar tiempo y frustración.

Error 1: Olvidar las comillas en un character

# ✗ R buscará un objeto llamado "hola" y dará error:
texto <- hola

# ✓ correcto:
texto <- "hola"

Error 2: Confundir == (comparar) con = (asignar)

x <- 10

# ✗ esto intenta asignar, no comparar:
if (x = 5) { ... }

# ✓ correcto:
if (x == 5) { ... }

Error 3: Usar c como nombre de objeto

# ✗ peligroso — "c" también es el nombre de la función c():
c <- 10
c(1, 2, 3)   # ahora "c" es 10, no la función → ERROR

# ✓ usa nombres descriptivos:
conteo <- 10

Error 4: Índices fuera de rango

# calificaciones tiene 6 elementos (índices del 1 al 6)
calificaciones[10]   # devuelve NA — bug silencioso

# ✓ siempre verifica con length() antes de indexar:
length(calificaciones)   # 6 → máximo índice permitido es 6

Error 5: Mayúsculas y minúsculas importan

Nombre <- "Ana"
print(nombre)   # Error: object 'nombre' not found
                # "Nombre" y "nombre" son dos objetos distintos

Error 6: Usar = en vez de <- para asignar (estilo)

# Funciona, pero no es la convención en R:
x = 5

# ✓ convención estándar de la comunidad R:
x <- 5

Parte 4 — El loop for

Un for repite el mismo bloque de código para cada elemento de una secuencia. Evita copiar y pegar el mismo código muchas veces.

Estructura:

for (variable_temporal in secuencia) {
    código que se repite en cada vuelta
}

Ejemplo 1: números del 1 al 5

for (i in 1:5) {
  cat("Vuelta número:", i, "\n")
}
#> Vuelta número: 1 
#> Vuelta número: 2 
#> Vuelta número: 3 
#> Vuelta número: 4 
#> Vuelta número: 5

Ejemplo 2: recorrer un vector de nombres

personas <- c("Ana", "Luis", "Maria", "Pedro", "Sandra")

for (persona in personas) {
  cat("Hola,", persona, "! Bienvenid@ a la clase de R.\n")
}
#> Hola, Ana ! Bienvenid@ a la clase de R.
#> Hola, Luis ! Bienvenid@ a la clase de R.
#> Hola, Maria ! Bienvenid@ a la clase de R.
#> Hola, Pedro ! Bienvenid@ a la clase de R.
#> Hola, Sandra ! Bienvenid@ a la clase de R.

Ejemplo 3: acceder a dos vectores al mismo tiempo con índice

asignaturas <- c("Estadística", "Programación", "Bases de Datos")
notas       <- c(9.5, 8.0, 9.0)

for (i in 1:length(asignaturas)) {
  cat(asignaturas[i], "->", notas[i], "\n")
}
#> Estadística -> 9.5 
#> Programación -> 8 
#> Bases de Datos -> 9

Ejemplo 4: for + if/else

for (i in 1:length(asignaturas)) {
  if (notas[i] >= 9) {
    cat(asignaturas[i], ": EXCELENTE (", notas[i], ")\n")
  } else {
    cat(asignaturas[i], ": BUENO     (", notas[i], ")\n")
  }
}
#> Estadística : EXCELENTE ( 9.5 )
#> Programación : BUENO     ( 8 )
#> Bases de Datos : EXCELENTE ( 9 )

Parte 5 — Ejercicio 1: tipos de objetos y paste0()

Instrucciones:

Crea 5 objetos con nombres descriptivos:

  • frase_base: un character con el texto "Me gusta correr"
  • km_mes: un integer con el valor 100
  • horas_dia: un numeric con el valor 1.5
  • horas_dos_dias: la suma de horas_dia + horas_dia
  • oracion: una oración con sentido usando paste0() y los 4 objetos anteriores

Imprime oracion y verifica el tipo de cada objeto con class().

Intenta resolverlo antes de ver la solución.

# --- TU CÓDIGO AQUÍ ---
Ver solución
frase_base     <- "Me gusta correr"   # character
km_mes         <- 100L                # integer
horas_dia      <- 1.5                 # numeric
horas_dos_dias <- horas_dia + horas_dia  # numeric: 1.5 + 1.5 = 3

oracion <- paste0(
  frase_base, " ", km_mes,
  " km al mes; en promedio corro ", horas_dia,
  " horas al dia, es decir, ", horas_dos_dias,
  " horas cada 2 dias."
)

print(oracion)
#> [1] "Me gusta correr 100 km al mes; en promedio corro 1.5 horas al dia, es decir, 3 horas cada 2 dias."
cat("\nTipos de los objetos:\n")
#> 
#> Tipos de los objetos:
cat("frase_base    :", class(frase_base),     "\n")
#> frase_base    : character
cat("km_mes        :", class(km_mes),         "\n")
#> km_mes        : integer
cat("horas_dia     :", class(horas_dia),      "\n")
#> horas_dia     : numeric
cat("horas_dos_dias:", class(horas_dos_dias), "\n")
#> horas_dos_dias: numeric
cat("oracion       :", class(oracion),        "\n")
#> oracion       : character

Parte 6 — Ejercicio 2: vectores y estadísticas

Instrucciones:

  1. Crea vec_pares: los números pares del 1 al 10
  2. Crea vec_enteros: los enteros del 1 al 100
  3. Calcula la media y la suma de ambos vectores
  4. Calcula las tres operaciones indicadas

Pista: para generar una secuencia rápida usa : (ej. 1:10)

# --- TU CÓDIGO AQUÍ ---
Ver solución
vec_pares   <- c(2, 4, 6, 8, 10)   # números pares del 1 al 10
vec_enteros <- 1:100                # enteros del 1 al 100

media_pares   <- mean(vec_pares)
suma_pares    <- sum(vec_pares)
media_enteros <- mean(vec_enteros)
suma_enteros  <- sum(vec_enteros)

cat("vec_pares   -> Media:", media_pares,   "| Suma:", suma_pares,   "\n")
#> vec_pares   -> Media: 6 | Suma: 30
cat("vec_enteros -> Media:", media_enteros, "| Suma:", suma_enteros, "\n")
#> vec_enteros -> Media: 50.5 | Suma: 5050
resultado1 <- suma_pares   * media_pares      # Suma × Media de vec_pares
resultado2 <- suma_enteros - media_enteros    # Suma − Media de vec_enteros
resultado3 <- suma_enteros / suma_pares       # Suma enteros / Suma pares

cat("\nOperaciones:\n")
#> 
#> Operaciones:
cat("suma_pares × media_pares      :", resultado1, "\n")
#> suma_pares × media_pares      : 180
cat("suma_enteros − media_enteros  :", resultado2, "\n")
#> suma_enteros − media_enteros  : 4999.5
cat("suma_enteros / suma_pares     :", resultado3, "\n")
#> suma_enteros / suma_pares     : 168.3333

Visualización rápida

Con R Markdown podemos mostrar gráficas directamente en el documento, sin necesidad de guardar archivos PNG por separado.

vec_pares   <- c(2, 4, 6, 8, 10)
vec_enteros <- 1:100
media_pares   <- mean(vec_pares)
media_enteros <- mean(vec_enteros)

par(mfrow = c(1, 3), mar = c(4, 4, 3, 1))

# Barras de vec_pares
barplot(vec_pares,
        names.arg = paste0("v", 1:5),
        col = "darkslategray", border = "white",
        main = "Vec_pares",
        xlab = "Elemento", ylab = "Valor", ylim = c(0, 13))
abline(h = media_pares, col = "tomato", lwd = 2, lty = 2)

# Histograma de vec_pares
hist(vec_pares, col = "#C1FFC1", border = "white",
     main = "Distribución vec_pares",
     xlab = "Valores", ylab = "Frecuencia", breaks = 5)
abline(v = media_pares, col = "tomato", lwd = 2, lty = 2)

# Línea de vec_enteros
plot(vec_enteros, type = "l", col = "#E87B4C", lwd = 2,
     main = "Vec_enteros (1 a 100)",
     xlab = "Índice", ylab = "Valor")
abline(h = media_enteros, col = "darkred", lwd = 2, lty = 2)

par(mfrow = c(1, 1))

Parte 7 — Ejercicio 3: escribe tu propio for

Instrucciones:

Tienes las calificaciones de 5 estudiantes. Escribe un for que recorra la lista e imprima para cada uno:

  • Si calificacion >= 60: "Nombre obtuvo X -> APROBADO"
  • Si calificacion < 60: "Nombre obtuvo X -> REPROBADO"

Datos:

nombres_est <- c("Ana", "Juan", "Maria", "Pedro", "Sofia")
califs      <- c(85, 45, 92, 58, 76)

Estructura de ayuda:

for (i in 1:length(nombres_est)) {
  if (califs[i] >= 60) {
    cat(...)   # APROBADO
  } else {
    cat(...)   # REPROBADO
  }
}
# --- TU CÓDIGO AQUÍ ---
Ver solución
for (i in 1:length(nombres_est)) {
  if (califs[i] >= 60) {
    cat(nombres_est[i], "obtuvo", califs[i], "-> APROBADO\n")
  } else {
    cat(nombres_est[i], "obtuvo", califs[i], "-> REPROBADO\n")
  }
}
#> Ana obtuvo 85 -> APROBADO
#> Juan obtuvo 45 -> REPROBADO
#> Maria obtuvo 92 -> APROBADO
#> Pedro obtuvo 58 -> REPROBADO
#> Sofia obtuvo 76 -> APROBADO

Parte 8 — Proyecto integrador

Pon en práctica todo lo aprendido: tipos de objetos, data.frame, estadísticas, for y gráficas.

Contexto: eres el coordinador académico de una carrera con 8 estudiantes. Tienes sus datos del semestre y necesitas generar un reporte completo.

Paso 1: Crear el data.frame

grupo <- data.frame(
  nombre       = c("Ana", "Luis", "Maria", "Carlos",
                   "Sofia", "Pedro", "Elena", "Jorge"),
  edad         = c(22L, 25L, 21L, 23L, 20L, 24L, 22L, 21L),
  calificacion = c(90.5, 58.0, 95.3, 82.1, 47.6, 76.4, 88.0, 63.5),
  carrera      = factor(c("Economia", "Derecho", "Economia", "Derecho",
                          "Economia", "Derecho", "Economia", "Derecho")),
  semestre     = c(4L, 6L, 2L, 8L, 2L, 4L, 6L, 8L)
)

print(grupo)
#>   nombre edad calificacion  carrera semestre
#> 1    Ana   22         90.5 Economia        4
#> 2   Luis   25         58.0  Derecho        6
#> 3  Maria   21         95.3 Economia        2
#> 4 Carlos   23         82.1  Derecho        8
#> 5  Sofia   20         47.6 Economia        2
#> 6  Pedro   24         76.4  Derecho        4
#> 7  Elena   22         88.0 Economia        6
#> 8  Jorge   21         63.5  Derecho        8

Paso 2: Estadísticas del grupo

promedio_grupo <- mean(grupo$calificacion)
mejor_nota     <- max(grupo$calificacion)
peor_nota      <- min(grupo$calificacion)
num_aprobados  <- sum(grupo$calificacion >= 60)
num_reprobados <- sum(grupo$calificacion <  60)

cat("Promedio del grupo  :", round(promedio_grupo, 2), "\n")
#> Promedio del grupo  : 75.17
cat("Calificación más alta:", mejor_nota, "\n")
#> Calificación más alta: 95.3
cat("Calificación más baja:", peor_nota,  "\n")
#> Calificación más baja: 47.6
cat("Aprobados  :", num_aprobados,  "de", nrow(grupo), "\n")
#> Aprobados  : 6 de 8
cat("Reprobados :", num_reprobados, "de", nrow(grupo), "\n")
#> Reprobados : 2 de 8

Paso 3: Reporte individual con for

cat("====== Reporte individual ======\n")
#> ====== Reporte individual ======
for (i in 1:nrow(grupo)) {

  nom <- grupo$nombre[i]
  cal <- grupo$calificacion[i]
  car <- as.character(grupo$carrera[i])
  sem <- grupo$semestre[i]

  estado  <- if (cal >= 60) "APROBADO" else "REPROBADO"
  mencion <- if (cal >= 90) "** Mención Honorífica **" else ""

  cat(nom, "|", car, "| Semestre", sem,
      "| Calificación:", cal, "|", estado, mencion, "\n")
}
#> Ana | Economia | Semestre 4 | Calificación: 90.5 | APROBADO ** Mención Honorífica ** 
#> Luis | Derecho | Semestre 6 | Calificación: 58 | REPROBADO  
#> Maria | Economia | Semestre 2 | Calificación: 95.3 | APROBADO ** Mención Honorífica ** 
#> Carlos | Derecho | Semestre 8 | Calificación: 82.1 | APROBADO  
#> Sofia | Economia | Semestre 2 | Calificación: 47.6 | REPROBADO  
#> Pedro | Derecho | Semestre 4 | Calificación: 76.4 | APROBADO  
#> Elena | Economia | Semestre 6 | Calificación: 88 | APROBADO  
#> Jorge | Derecho | Semestre 8 | Calificación: 63.5 | APROBADO

Paso 4: Gráfica de calificaciones

En R Markdown la gráfica aparece directamente en el documento — no necesitamos png() ni dev.off().

orden   <- order(grupo$calificacion, decreasing = TRUE)
cal_ord <- grupo$calificacion[orden]
nom_ord <- grupo$nombre[orden]
colores <- ifelse(cal_ord >= 60, "#4CAF50", "#E57373")

par(mar = c(5, 6, 4, 2))

barplot(
  cal_ord,
  names.arg = nom_ord,
  col       = colores,
  border    = "white",
  main      = "Calificaciones del Grupo — Semestre 2026",
  xlab      = "Estudiante",
  ylab      = "Calificación",
  ylim      = c(0, 110),
  las       = 1
)

abline(h = 60,             col = "red",  lwd = 2, lty = 2)
abline(h = promedio_grupo, col = "blue", lwd = 2, lty = 3)

legend(
  "topright",
  legend = c("Aprobado", "Reprobado",
             "Mín. aprobatoria (60)",
             paste0("Promedio (", round(promedio_grupo, 1), ")")),
  fill   = c("#4CAF50", "#E57373", NA, NA),
  lty    = c(NA, NA, 2, 3),
  col    = c(NA, NA, "red", "blue"),
  lwd    = c(NA, NA, 2, 2),
  border = NA,
  bty    = "n"
)


Resumen de la clase

Tipo Ejemplo class() Uso típico
numeric 1.64 "numeric" Medidas continuas
integer 25L "integer" Conteos, índices
character "Economía" "character" Texto, etiquetas
logical TRUE "logical" Condiciones, filtros
vector c(78, 85, 92) tipo base Series de valores del mismo tipo
factor factor(c(...)) "factor" Variables categóricas
data.frame data.frame(...) "data.frame" Tablas de datos (lo más usado)

Para la próxima clase

Practica estos conceptos con datos propios:

  1. Crea un data.frame con información de 5 personas que conozcas (nombre, edad, ciudad, una variable numérica de tu elección)
  2. Calcula la media y el máximo de tu variable numérica
  3. Usa un for para imprimir una oración sobre cada persona