lunes, 1 de febrero de 2010

Software estadístico- R - Trabajar con grandes conjuntos de datos. (II)

En la anterior entrada veíamos cómo importar un fichero de 4,7 Gb y un buen número de variables a un archivo legible en R. Se hacía a través de varios pasos y el uso de dos librerías adicionales , filehash y colbycol

Ahora vamos a importar el mismo fichero a través de la librería ff . Podéis ver detalles de sus instrucciones aquí.

La librería ff proporciona un medio de almacenamiento plano y de acceso rápido, proporcionando vistas físicas y virtuales de los datos. Uno de los objetos disponibles en esta librería se llama ffdf y es un análogo al data frame de R. A uno de estos objetos vamos a importar nuestro fichero a través de la función read.table.ffdf, construida para ser muy similar al read.table y almacenar ficheros con varias columnas (variables) en formato data frame, entre otras aplicaciones.

Una instrucción correcta para importar nuestros datos será por ejemplo:

>base_fichero<-read.table.ffdf("/home/datos/fichero1.txt",sep='|',fill=TRUE,x=NULL,first.rows=1e5,next.rows=8e5)

No comentaré opciones tradicionales de R(aquí las podemos meter cai todas sin problemas) , pero sí las nuevas:

-x=NULL se pone para indicar que nuestros datos no serán anexados a nada. Si tuviéramos otro ffdf y quisiéramos anexar, lo indicaríamos aquí.

-first.rows=1e5: La función read.table.ffdf lee "a trozos". Y el primer "trozo" a leer es importante porque desde aquí se toman datos relativos a factores, tipos de datos , valores etc. Por defecto, lee 1000 casos. En nuestro caso es mejor poner más para el correcto cálculo de niveles en los factores. Decir que esto se podrá recalcular posteriormente.

-next.rows=8e5: Después de la primera lectura , la función leerá y escribirá porciones del fichero original para irlos almacenando en los ficheros físicos que maneja. En esta opción se especifica el número de líneas a ller en cada pasada. Si se dispone de cierta capacidad de RAM (en mi caso unos 3Gb libres) , conviene dar manga ancha a este parámetro, puesto que redundará en mayor rapidez al disminuir el trabajo I/O.

Hay bastantes más opciones y quizá más eficientes. Pero deciros que con esto , soy capaz de leer todo el fichero original en un tiempo bastante razonable, y de una sola tacada. Es por tanto éste un método mejor que la combinación de filehash+ colbycol.

Para el uso de los datos veremos la manera de tomar los datos de una variable, denominada campo1 (ocupa la primera columna del fichero) de nuestro ffdf base_fichero:

>vector_campo1<- base_fichero[,1]
>vector_campo1<- base_fichero[,"campo1"]

Estas dos instrucciones realizan la misma labor, asignar a vector_campo1 los valores de la citada variable. El acceso a los datos de un ffdf se realiza con notación "matricial" [filas,columnas], por índice o por nombre. Si deseamos omitir filas o columnas , como en el ejemplo , simplemente se omite.

Otra posible acción es la siguiente:

>ajuste<-lm(base_fichero[,"campo1"]~ base_fichero[,"campo2"]

Y.... ahora igual que la otra vez, el sistema se queda sin memoria. Ya trabajamos en modo R clásico, poniendo los procesos en RAM . En las siguientes entradas referentes a esta serie veremos métodos para hacer análisis lo más acertados posible teniendo en cuenta esta adversidad.

Salimos..