read.csv() en R: acentos, separadores y comas decimales

read.csv() lee un archivo CSV y te lo devuelve como data frame. El problema es que, con archivos españoles, casi nunca funciona a la primera → o sale todo apelotonado en una columna, o los acentos aparecen rotos, o los importes se leen como texto.

Aquí van los tres fallos y su solución. Si buscas una visión general de cómo importar datos (también desde Excel), la tenemos en este otro artículo.

Ejemplo simple

datos <- read.csv("ventas.csv")

head(datos)

Si el archivo está en tu directorio de trabajo y viene "limpio", con esto basta. Puedes comprobar en qué carpeta estás con getwd().

Los tres problemas que te vas a encontrar

Separador de punto y coma. Excel en español guarda los CSV separando por ;, no por coma. Si abres el archivo y ves todo apelotonado en una sola columna, es esto:

datos <- read.csv("ventas.csv", sep = ";")

Coma decimal. En España usamos coma para los decimales, y R espera punto. El síntoma es que una columna que debería ser numérica te sale como texto:

datos <- read.csv("ventas.csv", sep = ";", dec = ",")

Acentos y eñes rotos. Si ves cosas como "Cataluña" convertida en símbolos raros, es un problema de codificación:

datos <- read.csv("ventas.csv", sep = ";", dec = ",", encoding = "UTF-8")

Si con UTF-8 sigue mal, prueba con fileEncoding = "latin1", que es lo que suelen usar los archivos generados en Windows.

Para este caso concreto R trae un atajo: read.csv2() ya viene configurada con punto y coma y coma decimal.

datos <- read.csv2("ventas.csv")

Ejemplo algo más completo: cargar y comprobar

Cargar el archivo es la mitad del trabajo. La otra mitad es verificar que ha entrado bien:

datos <- read.csv2("ventas.csv", stringsAsFactors = FALSE)

dim(datos)
str(datos)
colSums(is.na(datos))

str() te dice de qué tipo ha interpretado R cada columna → si una columna de importes aparece como chr en vez de num, es que el decimal no se ha leído bien y hay que volver al paso anterior.

colSums(is.na(datos)) te cuenta los valores ausentes de cada columna, que es justo lo que te va a estropear después cualquier mean() si no lo controlas.

stringsAsFactors = FALSE era imprescindible en versiones antiguas de R, donde el texto se convertía en factores automáticamente. Desde R 4.0 ya es el comportamiento por defecto, pero lo verás en mucho código antiguo.