web-dev-qa-db-fra.com

Alternatives efficaces à fusionner pour des données plus importantes. Cadres R

Je recherche une méthode efficace (à la fois en termes de ressources informatiques et d'apprentissage/implémentation) pour fusionner deux trames de données plus grandes (taille> 1 million/300 Ko RData).

"fusionner" dans la base R et "joindre" dans plyr semblent utiliser toute ma mémoire et planter efficacement mon système.

Exemple
charge trame de données de test

et essaye

test.merged<-merge(test, test)

ou

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

Le post suivant fournit une liste de fusion et d'alternatives:
Comment joindre (fusionner) des trames de données (interne, externe, gauche, droite)?

Les éléments suivants permettent l'inspection de la taille de l'objet:
https://heuristically.wordpress.com/2010/01/04/r-memory-usage-statistics-variable/

Données produites par anonym

30

Voici l'exemple obligatoire data.table:

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]
20
Josh O'Brien

Voici quelques timings pour les méthodes data.table vs data.frame.
L'utilisation de data.table est beaucoup plus rapide. En ce qui concerne la mémoire, je peux signaler de manière informelle que les deux méthodes sont très similaires (à moins de 20%) en utilisation 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 
26
bdemarest

Devez-vous faire la fusion en R? Sinon, fusionnez les fichiers de données sous-jacents à l'aide d'une simple concaténation de fichiers, puis chargez-les dans R. (je réalise que cela peut ne pas s'appliquer à votre situation - mais si c'est le cas, cela pourrait vous éviter beaucoup de maux de tête.)

0
David J.