Es cierto momento, me pidieron que utilizara mis habilidades en Expresiones Regulares (todo saben que estoy loco por el RegEx) para limpiar data que venia en un formato muy extraño dentro de un campo...algo como esto (No puedo publicar la data real por motivos obvios):
Type: [This is a test] Area: [My Area] Description: [This data is not right]
Lo que tenia que hacer basicamente, era tomar cada registro y generar una tabla con 3 campos que se veria mas o menos como esto...
Type | Area | Description |
---|---|---|
This is a test | My Area | This data is not right |
Comencé a pensar en que lenguage sería el mejor para este trabajo...Pensé en ABAP, Python...y luego por supuesto en...R...así que escogí R.
Los problemas que saltaron al instante fueron simples, como sacar la información de HANA y como enviarla de vuelta, además, aún cuando me considero un RegEx Hero, R no utiliza un esquema de RegEx muy estandard. Pensé en descargar la data de HANA como .CSV, limpiarla y luego subir el .CSV de vuelta a HANA...pero luego pensé que el trabajo extra no valía la pena...así que...my viejo y buen amigo RODBC entró en escena...aún cuando no esta soportado oficialmente por SAP, decidí que para este caso en particular, estaría perfecto...Podía leer la data de ida y vuelta y tenerla lista en HANA en muy poco tiempo.
Creemos una tabla y llamemosla BAD_DATA...y solo creemos 10 registros (Ya sé...Soy flojo)...
Así que aquí esta el script:
library("RODBC") ch<-odbcConnect("HANA_SERVER",uid="P075400",pwd="***") query<-("select case_description from P075400.BAD_DATA") CRM_TAB<-sqlQuery(ch,query) SR_Type<-c() SR_Area<-c() Description<-c() for(i in 1:nrow(CRM_TAB)){ mypattern = '\\[([^\\[]*)\\]' datalines = grep(mypattern,CRM_TAB$CASE_DESCRIPTION[i],value=T) getexpr = function(s,g)substring(s,g,g+attr(g,'match.length')-1) g_list = gregexpr(mypattern,datalines) matches = mapply(getexpr,datalines,g_list) result = gsub(mypattern,'\\1',matches) var<-0 i<-0 for(i in 1:length(result)){ var<-var+1 if(var==4){ break } if(var==1){ SR_Type<-append(SR_Type,result[i]) } if(var==2){ SR_Area<-append(SR_Area,result[i]) } if(var==3){ Description<-append(Description,result[i]) } } if(length(SR_Type)>length(Description)){ Description<-append(Description,NA) } if(length(SR_Type)>length(SR_Area)){ SR_Area<-append(SR_Area,NA) } } GOOD_DATA<-data.frame(SR_Type,SR_Area,Description,stringsAsFactors=FALSE) sqlDrop(ch,"GOOD_DATA",errors=FALSE) sqlSave(ch,GOOD_DATA,rownames="id") odbcClose(ch)
Así que basicamente, lo que hacemos es tomar la información que esta dentro de los corchetes [ ], luego pasarla a vectores para finalmente crear un Data.Frame y enviarlo de vuelta a HANA. Si se preguntan porque estoy comparando la longitud de los vectores para agregar valores NA, es muy simple...podemos tener algo como esto...
Type: [This is a test] Area: [My Area] Description: [This data is not right |
El último corchete...no es un cochete! Es un pipe (O como se llame en Español), así que el RegEx va a fallar y esto va a provocar que el vector este vacio y esto se puede poner feo...si esto sucedes, podemos poner un valor NA y al menos tener un valor...
Así que...cuando corremos nuestro programa...una nueva tabla llamada GOOD_DATA va a ser creada con toda la data limpia y lista para usar.
Elegante, no? -;)
Nos vemos en mi próximo blog! -:)
No comments:
Post a Comment