Convertir un bloc de données à un ensemble de données.table sans copie
J'ai un gros bloc de données (de l'ordre de plusieurs GO) que je voudrais convertir en data.table
. À l'aide de as.data.table
crée une copie de la trame de données, ce qui signifie que j'ai besoin de mémoire disponible pour être au moins deux fois la taille des données. Est-il un moyen de faire la conversion sans une copie?
Voici un exemple simple à démontrer:
library(data.table)
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))
gc(reset=TRUE)
tracemem(data)
data <- as.data.table(data)
gc()
Avec sortie:
library(data.table)
# data.table 1.8.10 For help type: help("data.table")
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))
gc(reset=TRUE)
# used (Mb) gc trigger (Mb) max used (Mb)
# Ncells 303759 16.3 597831 32.0 303759 16.3
# Vcells 100442572 766.4 402928632 3074.2 100442572 766.4
tracemem(data)
# [1] "<0x363fda0>"
data <- as.data.table(data)
# tracemem[0x363fda0 -> 0x31e4260]: copy as.data.table.data.frame as.data.table
gc()
# used (Mb) gc trigger (Mb) max used (Mb)
# Ncells 304519 16.3 597831 32.0 306162 16.4
# Vcells 100444242 766.4 322342905 2459.3 200933219 1533.0
Vous devez vous connecter pour publier un commentaire.
Ce qui est disponible à partir de v1.9.0+. De NEWS:
Ceci est en accord avec
data.table
convention d'affectation des noms de tous lesset*
fonctions modifie par référence.:=
est le seul autre qui modifie également par référence.Voir l'histoire pour les plus âgés (aujourd'hui obsolète) réponses.
settruelength
faire?settruelength
fait exactement cela, définit la longueur. VérifierSET_TRUELENGTH
dans R_internals.h (ou envir.c). Il a été conçu pour être utilisé pour de sur-allocation en R à un certain point, mais n'a jamais pu être utilisé comme prévu (IIRC à partir de la lecture d'un post sur r-devel il y a quelques mois). Ici, nous avons mis à 0 explicitement avantalloc.col
appeler parce que les versions R > 2.14 n'est pas définie par défaut (à partir de données.table des commentaires sous settruelength C de la fonction). Pourquoi nous avons besoin d'elle, je ne suis pas sûr.. parce que, dansalloc.col
, nous ne le véritable longueur de toute façon.truelength
.settruelength
commande ici?truelength
membre de la R du vecteur d'en-tête n'était pas initialisé par le R. C si vous n'avez pas d'initialiser une variable, il a pas défini le contenu (tout ce qui se trouve dans ce morceau de RAM précédemment).data.table()
et similaires créateurs initialisertruelength
à 0 avant d'appeleralloc.col
pour la compatibilité avec les pré R 2.14.0.alloc.col
regardetruelength
comme une entrée (0 est-à-dire truelength==longueur). À un moment j'ai pensé de données.table a besoin de dépendre de la R>=2.14.0 à cause de cela, mais a réussi à garder de la R>=la version 2.12.0. Je test avec R2.12.0 avant chaque sortie, à CRAN.as.data.table
renvoie une copie.