Capítulo14 Errores comunes y cómo resolverlos

Fecha de la última revisión

## [1] "2026-09-09"

Equivocarse es parte normal de programar. Hasta quienes llevan años usando R ven errores todos los días. La destreza que de verdad importa no es evitar los errores, sino aprender a leerlos y resolverlos, porque cuando hagas tu propio análisis nadie va a haber “arreglado” el código de antemano.

Un mensaje de error casi siempre te dice dos cosas: qué salió mal y, muchas veces, dónde (la función o la línea). Léelo despacio de arriba hacia abajo; la primera línea suele ser la más importante.

En este capítulo provocamos a propósito los errores más frecuentes para que los reconozcas cuando aparezcan. En cada ejemplo verás el mensaje real de R y luego cómo resolverlo.


14.1 Temas

  • Cómo se lee un mensaje de error
  • La diferencia entre un error, una advertencia y un mensaje
  • could not find function y there is no package called
  • object ... not found
  • Operaciones con texto: non-numeric argument y NAs introduced by coercion
  • unused argument, = frente a ==
  • object of type 'closure' is not subsettable y $ operator is invalid for atomic vectors
  • NA y na.rm
  • Archivos que no aparecen y direcciones de internet que no responden
  • Un método general para resolver errores

library(dplyr)

14.2 Error, advertencia y mensaje: no son lo mismo

Los tres se imprimen en rojo en la consola, y por eso al principio asustan por igual. Pero solo uno de los tres detiene el trabajo.

  • Un error (Error in ...) significa que R no pudo hacer lo que le pediste. La línea no se ejecutó y no hay resultado. Hay que arreglarlo.
  • Una advertencia (Warning message:) significa que R sí hizo algo, pero sospecha que no es lo que querías. Hay resultado, y por eso las advertencias son más peligrosas que los errores: es fácil seguir de largo con un número equivocado.
  • Un mensaje (Attaching package:, Joining with by = ...) es solo información. R te cuenta lo que está haciendo y no hay nada que arreglar.

El error te para; la advertencia te deja seguir. Si tu análisis produce una advertencia y tú la ignoras, el número que reportas puede estar mal y nadie te va a avisar. Léelas todas.


14.3 could not find function

promedio(c(2, 4, 6))
## Error in `promedio()`:
## ! could not find function "promedio"

could not find function "promedio" significa que R no conoce esa función. Las tres causas más comunes son: (1) escribiste mal el nombre, (2) olvidaste activar el paquete con library(), o (3) la función es de otro paquete que no está instalado. Solución: revisa la ortografía y corre el library() correspondiente.

R distingue mayúsculas de minúsculas, así que Sqrt no es lo mismo que sqrt:

Sqrt(9)
## Error in `Sqrt()`:
## ! could not find function "Sqrt"

Si una función “no existe” pero estás seguro de que sí, revisa las mayúsculas: sqrt(), no Sqrt(); TRUE, no True.


14.4 object ... not found

resultado + 1
## Error:
## ! object 'resultado' not found

object 'resultado' not found quiere decir que usaste una variable que todavía no existe. Suele pasar cuando hay una errata en el nombre o cuando no corriste antes el bloque que crea esa variable. Solución: crea la variable primero (resultado <- ...) y ejecuta los bloques en orden.


14.5 non-numeric argument to binary operator

"3" * 2
## Error in `"3" * 2`:
## ! non-numeric argument to binary operator

R no puede multiplicar texto por un número: "3" (con comillas) es una cadena de caracteres, no el número 3. Conviértelo con as.numeric("3") antes de operar.


14.6 unused argument

mean(c(1, 2, 3), n = 2)
## [1] 2

unused argument (n = 2) significa que le pasaste a la función un argumento que no reconoce. Casi siempre es un nombre de argumento equivocado. Revisa la ayuda con ?mean para ver los nombres correctos (aquí no existe n; quizás querías trim).


14.7 Confundir = con ==

filter(mtcars, cyl = 6)
## Error in `filter()`:
## ! We detected a named input.
## ℹ This usually means that you've used `=` instead
##   of `==`.
## ℹ Did you mean `cyl == 6`?

Dentro de filter() (y para comparar en general) se usa ==, no =. Un solo = asigna; el doble == compara. Por suerte, dplyr hasta te sugiere la corrección: cyl == 6.


14.8 El caso especial de NA (no es un error, pero engaña)

Esto no produce un error, pero el resultado sorprende a muchos:

mean(c(1, 2, NA))
## [1] NA

Casi cualquier cálculo con un valor faltante (NA) devuelve NA. No es un error: R te avisa que no puede calcular la media sin saber ese dato. La solución es pedir que ignore los faltantes con na.rm = TRUE:

mean(c(1, 2, NA), na.rm = TRUE)
## [1] 1.5

14.9 cannot open file ... No such file or directory

read.csv("mis_datos_que_no_existen.csv")
## Error in `file()`:
## ! cannot open the connection

Este error aparece cuando R no encuentra el archivo. Las causas típicas son: el nombre está mal escrito, el archivo está en otra carpeta, o tu directorio de trabajo no es el que crees. La mejor prevención es trabajar siempre dentro de un Proyecto de RStudio y usar rutas relativas como "Datos/mi_archivo.csv".


14.10 cannot open URL (descargar datos de internet)

Cuando un capítulo baja datos en vivo, por ejemplo con fread("https://…") o download.file(), y no hay conexión (o el servidor no responde), verás algo como esto:

Error in download.file(...) :
  cannot open URL 'https://ejemplo.com/datos.csv'

(No ejecutamos ese código aquí a propósito, para no depender de la red.)

cannot open URL no es un error de tu código: significa que no hay internet o que el servidor está caído o lento. Verifica tu conexión y vuelve a intentar.

Una técnica profesional para que tu análisis no se caiga por completo cuando esto pasa es tryCatch(): intenta la descarga en vivo y, si falla, usa una copia local que guardaste antes. Este es exactamente el patrón que usamos en el capítulo de mapas:

datos <- tryCatch(
  fread("https://ejemplo.com/datos.csv"),          # intenta en vivo
  error = function(e) readr::read_csv("Datos/copia_local.csv")  # si falla, usa la copia
)

Buena práctica: descarga los datos una vez, guárdalos con write_csv() en la carpeta Datos/, y en adelante trabaja con la copia local. Así tu análisis es reproducible aunque no tengas internet.


14.11 there is no package called ...

library(paqueteQueNoExiste)
## Error in `library()`:
## ! there is no package called 'paqueteQueNoExiste'

Este mensaje no es el mismo que could not find function. Aquí el paquete no está instalado en la computadora. Instalar y activar son dos pasos distintos: install.packages("nombre") se hace una sola vez por computadora y baja el paquete de internet; library(nombre) se hace en cada sesión y lo activa. Si escribes library() de algo que nunca instalaste, sale este error.

install.packages() va entre comillas y library() normalmente sin comillas. Y nunca dejes install.packages() dentro de un script que vas a compartir: obliga a los demás a reinstalar el paquete cada vez que corren tu análisis.


14.12 object of type 'closure' is not subsettable

Este mensaje tiene fama de incomprensible, y en realidad dice algo sencillo. “Closure” es la palabra que usa R para decir función. El error aparece cuando tratas a una función como si fuera una tabla:

data$edad
## Error in `data$edad`:
## ! $ operator is invalid for atomic vectors

data es una función de R, no tus datos. Cuando le pides data$edad, R contesta que a una función no se le puede sacar una columna. Pasa siempre por lo mismo: le pusiste a tu tabla un nombre que ya usa R (data, df, mean, sum, c, t) y luego olvidaste crearla, o el bloque que la creaba no corrió. Solución: dale a tus tablas nombres propios (millas_2008, datos_covid) y ejecuta los bloques en orden.


14.13 $ operator is invalid for atomic vectors

x <- c(a = 1, b = 2, c = 3)
x$a
## Error in `x$a`:
## ! $ operator is invalid for atomic vectors

El $ solo funciona en tablas y listas, no en vectores. Un vector no tiene columnas, tiene posiciones y a veces nombres. Para sacarle un elemento se usan corchetes: x["a"] conserva el nombre y x[["a"]] devuelve el valor pelado.

x["a"]
## a 
## 1
x[["a"]]
## [1] 1

14.14 NAs introduced by coercion (una advertencia, no un error)

as.numeric(c("3", "4", "cinco"))
## Warning: NAs introduced by coercion
## [1]  3  4 NA

R hizo la conversión, pero lo que no pudo convertir lo dejó en NA. No hay error, hay resultado, y por eso este es un caso donde ignorar la advertencia sale caro: si esa columna venía de un Excel con una celda que decía “n/a” o “sin dato”, acabas de convertirla en un NA sin darte cuenta. Antes de as.numeric(), mira siempre qué valores raros trae la columna.


14.15 longer object length is not a multiple ... (reciclaje)

c(1, 2, 3, 4) + c(10, 20, 30)
## Warning in c(1, 2, 3, 4) + c(10, 20, 30): longer object length is not a
## multiple of shorter object length
## [1] 11 22 33 14

Cuando dos vectores tienen largos distintos, R repite el corto hasta completar el largo, en vez de negarse. Eso se llama reciclaje. Si los largos encajan (4 y 2) lo hace en silencio; si no encajan (4 y 3) avisa con esta advertencia. En cualquiera de los dos casos, si tus dos columnas debían tener el mismo largo, el resultado está mal. Revisa con length() o nrow().


14.16 Un método general para resolver errores

  1. Lee el mensaje completo, sobre todo la primera línea.
  2. Identifica la función o la línea que menciona.
  3. Pregúntate: ¿escribí bien el nombre?, ¿activé el paquete?, ¿existe la variable?, ¿el archivo está donde digo?
  4. Si te atoras, copia el mensaje de error y búscalo en internet: casi siempre alguien ya tuvo el mismo problema.
  5. Reduce el problema a un ejemplo mínimo que lo reproduzca; muchas veces al simplificarlo descubres la causa.

Guarda la calma: un error no significa que “no sirves para esto”. Significa que R necesita que le aclares algo. Cada error que resuelves te hace mejor analista.


14.17 Ejercicios del capítulo

Sobre los ejercicios de este capítulo. Cada ejercicio se entrega con tres cosas: el script, el resultado (que el bloque corra) y una explicación en palabras. Aquí la explicación pesa más que en otros capítulos: lo que se evalúa es que sepas leer el mensaje, no solo que el código acabe corriendo. Los ejercicios usan millas y diamantes del paquete datos, no mtcars ni iris, que son los del capítulo. La hoja completa para entregar está en Ejercicios/Ejercicios_Capitulo_14_errores.Rmd.

Truco para que tu documento compile aunque muestres un error a propósito: añade error=TRUE a las opciones del bloque, como se hace en este capítulo.

14.17.1 Ejercicio 1. Leer el mensaje

Estas cinco líneas están rotas, cada una por una razón distinta:

Filter(millas, clase == "compact")

millas$autopsta

filter(millas, anio = 2008)

"8" + millas$cilindros[1]

mean(millas$clase)

Para cada una: córrela con error=TRUE, copia lo que salió, explica en una oración qué significa, y escribe debajo la versión corregida.

Verificación: las cinco versiones corregidas deben correr limpias, sin error y sin advertencia.

En palabras: solo tres de las cinco producen un error que detiene la línea. ¿Cuáles son las otras dos, qué devuelven, y por qué son más peligrosas que las tres que sí fallan de frente?

# Escribe tu código aquí

14.17.2 Ejercicio 2. Instalar no es activar

Sin activar ningún paquete nuevo, corre rollmean(1:10, 3) en un bloque con error=TRUE. Después arréglalo de dos maneras distintas: una con library() y otra escribiendo paquete::funcion().

Verificación: las dos versiones corregidas deben devolver el mismo vector de 8 valores.

En palabras: ¿qué mensaje distinto habrías visto si el paquete zoo no estuviera instalado en tu computadora? ¿Por qué no conviene dejar install.packages("zoo") dentro del script que entregas?

# Escribe tu código aquí

14.17.3 Ejercicio 3. El NA no es un error

Datos: millas. Haz una copia y métele valores faltantes a propósito:

millas_na <- millas

millas_na$autopista[c(3, 17, 100)] <- NA

Calcula el promedio de autopista en millas_na de tres maneras: sin na.rm, con na.rm = TRUE, y quitando antes las filas con NA usando filter(!is.na(autopista)).

Verificación: la primera devuelve NA; la segunda y la tercera devuelven el mismo número, calculado sobre 231 filas.

En palabras: las tres son distintas maneras de tratar el mismo problema. ¿Cuándo sería un error de análisis usar na.rm = TRUE sin pensarlo?

# Escribe tu código aquí

14.17.4 Ejercicio 4. =, == y <-

Datos: diamantes. Escribe tres líneas, cada una en su propio bloque con error=TRUE si hace falta:

  1. filter(diamantes, corte = "Ideal")
  2. filter(diamantes, corte == "Ideal")
  3. diamantes_ideal = filter(diamantes, corte == "Ideal")

Verificación: la segunda y la tercera producen la misma tabla; la primera no produce ninguna.

En palabras: el = de la línea 1 y el = de la línea 3 son el mismo signo, pero solo uno de los dos está mal. Explica qué hace = en cada sitio y por qué en el curso preferimos <- para asignar.

# Escribe tu código aquí

14.17.5 Ejercicio 5. El ejemplo mínimo

Este bloque se cae, pero el mensaje no dice en cuál de los cuatro pasos:

resumen <- diamantes |>

filter(quilate > 0.5) |>

group_by(corte) |>

summarise(precio_medio = mean(Precio))

Encuentra el paso que falla reduciendo el problema: corre el primer paso solo, luego los dos primeros, y así hasta que reaparezca el error.

Verificación: cuando lo arregles, la tabla debe tener 5 filas, una por cada nivel de corte.

En palabras: ¿en qué paso estaba el problema y cómo lo supiste? Explica por qué reducir el código a un ejemplo mínimo es más rápido que releer las cuatro líneas enteras.

# Escribe tu código aquí

14.17.6 Ejercicio 6 (BONO). Que no se caiga por culpa del internet

Guarda una tabla pequeña de millas en Datos/millas_copia.csv con write_csv(). Después escribe un tryCatch() que intente leer un archivo desde una dirección de internet que no existe y que, al fallar, lea tu copia local.

Verificación: el bloque debe correr sin error y devolver la tabla de tu copia local.

En palabras: ¿qué diferencia hay entre este tryCatch() y simplemente poner error=TRUE en el bloque?

# Escribe tu código aquí