Limpiar datos en R: fechas, importes y nombres

Un archivo real rara vez viene limpio. Este tiene fechas como texto, importes con signo de pesos, nombres mezclados, un duplicado y una fecha vacía: gastos_sucios.csv.

El archivo

library(tidyverse)
gastos <- read_csv("https://grafoso.com/r/gastos_sucios.csv", show_col_types = FALSE)
gastos
# A tibble: 6 × 3
  Fecha      Proveedor     Importe   
  <chr>      <chr>         <chr>     
1 05/01/2026 papelería sol $1,250.50 
2 12/01/2026 PAPELERÍA SOL $980.00   
3 12/01/2026 PAPELERÍA SOL $980.00   
4 03/02/2026 Taller  Río   $ 2,300.00
5 20/02/2026 taller río    $450.75   
6 <NA>       Farmacia Mar  $120.00

Convertir cada columna

dmy() lee día, mes y año. parse_number() ignora el signo de pesos y las comas. str_squish() quita espacios de más, y str_to_title() iguala mayúsculas.

limpios <- gastos |>
  mutate(
    fecha = dmy(Fecha),
    proveedor = str_to_title(str_squish(Proveedor)),
    importe = parse_number(Importe)
  ) |>
  select(fecha, proveedor, importe)
limpios
# A tibble: 6 × 3
  fecha      proveedor     importe
  <date>     <chr>           <dbl>
1 2026-01-05 Papelería Sol   1250.
2 2026-01-12 Papelería Sol    980 
3 2026-01-12 Papelería Sol    980 
4 2026-02-03 Taller Río      2300 
5 2026-02-20 Taller Río       451.
6 NA         Farmacia Mar     120

La tabla abrevia 1,250.50 como 1250. al mostrarla, pero el valor es exacto.

Quitar duplicados y vacíos

limpios |>
  distinct() |>
  filter(!is.na(fecha))
# A tibble: 4 × 3
  fecha      proveedor     importe
  <date>     <chr>           <dbl>
1 2026-01-05 Papelería Sol   1250.
2 2026-01-12 Papelería Sol    980 
3 2026-02-03 Taller Río      2300 
4 2026-02-20 Taller Río       451.

Antes de borrar, revisa: dos gastos iguales podrían ser reales, y una fila sin fecha podría ser un gasto que falta capturar.

Preguntas frecuentes

¿Y si la fecha viene como mes/día/año?

Usa mdy(). Para año-mes-día, ymd(). Elegir mal puede cambiar la fecha sin avisar: revisa los resultados.

¿parse_number sirve con comas decimales?

Sí, indícalo con locale = locale(decimal_mark = ",", grouping_mark = ".").

Fuentes oficiales