2012-06-21 9 views
23

Estoy buscando un método eficiente (tanto de recursos informáticos como de aprendizaje/implementación) para fusionar dos marcos de datos más grandes (tamaño> 1 millón/300 KB de datos).Alternativas eficientes para fusionar para data.frames más grandes R

"fusionar" en la base R y "unir" en plyr parecen agotar toda mi memoria y bloquear mi sistema.

Ejemplo
carga test data frame

y tratar

test.merged<-merge(test, test) 

o

test.merged<-join(test, test, type="all") 
    -

El siguiente post ofrece una lista de alternativas de combinación y:
How to join (merge) data frames (inner, outer, left, right)?

El siguiente permite la inspección tamaño del objeto:
https://heuristically.wordpress.com/2010/01/04/r-memory-usage-statistics-variable/

Los datos producidos por anonym

+8

sql.df o data.table? –

+0

Después de destripar las agradables respuestas a continuación, pude encontrar: http://stackoverflow.com/questions/4322219/whats-the-fastest-way-to-merge-join-data-frames-in-r (aunque el la pregunta no era sobre un gran df, sino sobre cómo ahorrar milisegundos, obtuvo respuestas similares a las que se muestran a continuación). –

Respuesta

18

Aquí está la obligatoriedad data.table ejemplo:

library(data.table) 

## Fix up your example data.frame so that the columns aren't all factors 
## (not necessary, but shows that data.table can now use numeric columns as keys) 
cols <- c(1:5, 7:10) 
test[cols] <- lapply(cols, FUN=function(X) as.numeric(as.character(test[[X]]))) 
test[11] <- as.logical(test[[11]]) 

## Create two data.tables with which to demonstrate a data.table merge 
dt <- data.table(test, key=names(test)) 
dt2 <- copy(dt) 
## Add to each one a unique non-keyed column 
dt$X <- seq_len(nrow(dt)) 
dt2$Y <- rev(seq_len(nrow(dt))) 

## Merge them based on the keyed columns (in both cases, all but the last) to ... 
## (1) create a new data.table 
dt3 <- dt[dt2] 
## (2) or (poss. minimizing memory usage), just add column Y from dt2 to dt 
dt[dt2,Y:=Y] 
+0

Gracias por la gran respuesta. Supongo que si desea mantener el orden original, agregue una columna 1: grow (df) y úselo como primer elemento de la clave. –

+0

@ EtienneLow-Décarie - Esa es una buena pregunta. Creo que desea agregar dicha columna, pero ** no ** la convierte en un elemento de la clave. De esta forma, puede usarlo para reordenar los datos en cualquier momento. (No debe ser parte de la clave ya que es solo un marcador de orden, no un identificador de variable/grupo que tiene el mismo significado en diferentes conjuntos de datos). –

+2

¿data.table deletrea el final de la necesidad de aplicar y plyr? ¡Muy impresionante! –

0

No hay que hacer la fusión en R? Si no, combine los archivos de datos subyacentes con una simple concatenación de archivos y luego cárguelos en R. (me doy cuenta de que esto puede no aplicarse a su situación, pero si lo hace, podría ahorrarle muchos dolores de cabeza)

+2

Tiene que hacerse en vivo en R ya que es un paso en una rutina de optimización. Escribir en el disco probablemente sea un cuello de botella. Gracias sin embargo. –

20

Éstos son algunos horarios para las vs. data.frame métodos data.table.
Usar data.table es mucho más rápido. Con respecto a la memoria, puedo informar informalmente que los dos métodos son muy similares (dentro del 20%) en el uso de RAM.

library(data.table) 

set.seed(1234) 
n = 1e6 

data_frame_1 = data.frame(id=paste("id_", 1:n, sep=""), 
          factor1=sample(c("A", "B", "C"), n, replace=TRUE)) 
data_frame_2 = data.frame(id=sample(data_frame_1$id), 
          value1=rnorm(n)) 

data_table_1 = data.table(data_frame_1, key="id") 
data_table_2 = data.table(data_frame_2, key="id") 

system.time(df.merged <- merge(data_frame_1, data_frame_2)) 
# user system elapsed 
# 17.983 0.189 18.063 


system.time(dt.merged <- merge(data_table_1, data_table_2)) 
# user system elapsed 
# 0.729 0.099 0.821 
Cuestiones relacionadas