Loading...
 
ADUP - R

ADUP - R


Tidyverse readr::read_csv et al.: com evitar problemes de parsejat de columnes

posts: 51

Hola:

Avís per a navegants: per als enamorats del mon "tidyverse" (del Hadley Wickam), i que empreu readr::read_csv, a la feina em trobava de tant en quant amb problemes de parsejat de valors a columnes (per al tipus de columna que identifica automàticament a partir dels valors que troba en els 1000 registres de cada columna).

Tenia pendent com detectar millor quan es donava el problema i com evitar-ho (en cas de ser greu), i ara ja tinc una solució, sense tornar a la funció read.csv del R core, que és molt més lenta (i es nota la diferència quan el joc de dades és gran).

Quan read_csv té problemes de parsejat en alguna línia, aquella fila no l'assigna a dins del data.frame, però per omisió, continua llegint les següents línies.

Sovint en el meu cas és per que ha identificat valors numerics en les primeres 1000 línies (o NA), però desenes de milers de registres per sota, apareix algun valor diferent (amb caracters, o el que sigui). Llavors ens mostra un resum dels problemes, i en quina columna els troba, a més de mostrar-los el llistat sencer de les assignacions de tipus de valors en cada columna que ha trobat.

file1<-"dades/Peticio123_dades1_1812.csv"
read_csv(file1)
## Warning: 3162 parsing failures.
##  row            col           expected actual                               file
## 1010 TIPUS_VIVENDA  1/0/T/F/TRUE/FALSE    COL 'dades/Peticio123_dades1_1812.csv'
## 1010 MARCA_COLECTIU 1/0/T/F/TRUE/FALSE    S   'dades/Peticio123_dades1_1812.csv'
## 1443 TIPUS_VIVENDA  1/0/T/F/TRUE/FALSE    COL 'dades/Peticio123_dades1_1812.csv'
## 1443 MARCA_COLECTIU 1/0/T/F/TRUE/FALSE    S   'dades/Peticio123_dades1_1812.csv'
## 1474 TIPUS_VIVENDA  1/0/T/F/TRUE/FALSE    FAM 'dades/Peticio123_dades1_1812.csv'
## .... .............. .................. ...... ..................................
## See problems(...) for more details.
Parsed with column specification:
cols(
    .default = col_character(),
    DBOID_VIVENDA = col_double(),
    CODI_CARRER = col_double(),
    RFL = col_double(),
    TIPUS_VIVENDA = col_logical(),
    MARCA_COLECTIU = col_logical(),
    NPER = col_double(),
    COORD_X = col_double(),
    COORD_Y = col_double()
    )


Per evitar els problemes, forço a que readr agafi com a caracters o factors les columnes on hi ha el problema, i llavors ja no tinc cap error de parsejat. Copio el codi per especificar els tipus de columnes que m'ha mostrat la consola d'R, i canvio el tipus de columna conflictiva al que m'interessi. En aquest cas, canvio de col_logical a col_factor per a TIPUS_VIVENDA i MARCA_COLECTIU.

file1<-"dades/Peticio123_dades1_1812.csv"
read_csv(file1, col_types = cols(
    .default = col_character(),
    DBOID_VIVENDA = col_double(),
    CODI_CARRER = col_double(),
    RFL = col_double(),
    TIPUS_VIVENDA = col_factor(),
    MARCA_COLECTIU = col_factor(),
    NPER = col_double(),
    COORD_X = col_double(),
    COORD_Y = col_double()
    )
  )
  stop_for_problems(df1)


I llavors ja no tenim cap missatge d'error.

I a més, per a evitar que el codi continui si hi ha problemes de parsejat, afegeixo la instrucció stop_for_problems() per a que s'aturi fins que arregli el problema, per a evitar mals majors que passin inadvertits si senzillament s'ignoren les files potencialment conflictives en casos d'autodescobrir el tipus de columna amb poc % de casos respecte al joc de dades real que volem llegir.

Per si li serveix a algú altre... jo feia temps que tenia pendent posar-m'hi a trobar una forma de prevenir aquest possible problema als meus scripts (i que em passes de forma inadvertida) tot mantenint una certa velocitat de lectura de les dades d'origen.