2010-02-03 10 views
38

Tengo algunos archivos de datos delimitados muy grandes y Quiero procesar solo ciertas columnas en R sin tomar el tiempo y la memoria para crear un data.frame para el todo el archivoFormas de leer solo seleccionar columnas de un archivo en R? (Un medio feliz entre `read.table` y` scan`?)

Las únicas opciones que conozco son read.table que es muy derrochador cuando solo quiero un par de columnas o scan que parece demasiado bajo para lo que quiero.

¿Hay una mejor opción, ya sea con R puro o quizás llamando a algún otro script de shell para hacer la extracción de columna y luego usar scan o read.table en su salida? (¿Qué lleva a la pregunta de cómo llamar a un script de shell y capturar su salida en R?).

+0

Todo un conjunto de respuestas útiles aquí. Cualquiera de ellos sería útil para un contexto dado. El aceptado fue simplemente el más cercano a mi caso real e incluyó un fragmento de código. (Podría haber elegido a Dirk pero parece que ya tiene mucha reputación ;-)) –

+6

La mejor respuesta es en una nueva pregunta http://stackoverflow.com/q/5788117/168747 – Marek

Respuesta

34

A veces hacer algo como esto cuando tengo los datos en un archivo delimitado por tabuladores:

df <- read.table(pipe("cut -f1,5,28 myFile.txt")) 

Eso permite que cut haga la selección de datos, lo que puede hacer sin usar mucha memoria.

Ver Only read limited number of columns para la versión R puro, usando "NULL" en el argumento colClasses a read.table.

+1

Su primer ejemplo es más o menos exactamente lo que terminé usando.(awk en lugar de cortar en mi caso debido a un formato de archivo delimitado irregular). Su segundo ejemplo no es verdaderamente equivalente, tal como lo entiendo. ¿No va a crear todo el 'data.frame' solo para tirarlo de nuevo? Cuando quiero 2 de 10 columnas de un millón de filas, el rendimiento es muy diferente. –

+11

No, el equivalente R puro sería algo así como (suponiendo 28 columnas) 'mycols <- rep (NULL, 28); mycols [c (1,5,28)] <- NA; df <- read.table (file, colClasses = mycols) ' –

+1

@DirkEddelbuettel Acabo de descubrir esto. Parece que 'NULL' debe estar entre comillas. – JackeJR

18

Una posibilidad es usar pipe() en lugar del nombre de archivo y tener awk o filtros similares extraer solo las columnas que desee.

Ver help(connection) para más información sobre pipe y amigos.

Edición: read.table() También puede hacer esto para usted si usted es muy explícito acerca de colClasses - un valor de NULL para una columna dada se salta la columna alltogether. Ver help(read.table). Entonces, tenemos una solución en la base R sin paquetes o herramientas adicionales.

7

Creo que el enfoque de Dirk es sencillo y rápido. Una alternativa que he usado es cargar los datos en sqlite que se carga mucho más rápido que read.table() y luego sacar solo lo que desea. el paquete sqldf() hace que todo esto sea bastante fácil. Here's a link a una respuesta anterior de desbordamiento de pila que da ejemplos de código para sqldf().

3

Esto es probablemente más de lo necesario, pero si usted está operando en grandes conjuntos de datos, entonces también puede echar un vistazo a the HadoopStreaming package cuales proporciona un mapa a reducir el uso de rutina de Hadoop.

7

Hay un paquete, colbycol, diseñado para hacer exactamente lo que busca:

http://cran.r-project.org/web/packages/colbycol/index.html

+1

En realidad, esto parece que todavía procesa todas las columnas pero sin las restricciones de memoria. Puede ser muy útil en un contexto ligeramente diferente. –

+2

Este paquete ya no está disponible en CRAN. –

Cuestiones relacionadas