2013-12-03 3 views
54

У меня есть большой фрейм данных (порядка нескольких ГБ), который я бы хотел преобразовать в data.table. Использование as.data.table создает копию фрейма данных, что означает, что мне нужна доступная память как минимум в два раза превышающая размер данных. Есть ли способ сделать преобразование без копии?Преобразование кадра данных в таблицу данных без копии

Вот простой пример, чтобы продемонстрировать:

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() 

С выходом:

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 

ответ

59

Это доступно от v1.9.0+. От NEWS:

O После this S.O. post, функция setDT в настоящее время осуществляется, которая принимает list (с именем и/или безымянная), data.frame (или data.table) в качестве входных данных и возвращает один и тот же объект в качестве data.tableпосредством ссылки (без какой-либо копии). См. Примеры ?setDT.

Это находится в соответствии с data.table именования - все set* функции модифицирует посредством ссылки. := - единственный, который также изменяет ссылку.

require(data.table) # v1.9.0+ 
setDT(data) # converts data which is a data.frame to data.table *by reference* 

Смотреть историю старых (ныне устаревших) ответов.

+0

+1 Еще один отличный ответ, и я узнаю немного больше. Спасибо Аруну. –

+0

@Arun: Спасибо за подробный ответ. Я действительно спрашивал, как преобразовать фрейм данных в таблицу data.table, но был неаккуратным в создании примера игрушек, я обновлю свой вопрос, чтобы сделать его фреймом данных. Будет ли такая же идея работать для кадра данных, например, избавиться от первых двух setattr, поскольку кадр данных уже имеет их и сохраняет остальные? –

+0

@YT, если вы хотите получить «data.frame» на «data.table», то, конечно, то, что вы говорите, правильно. Если вы имеете в виду список data.frames, вам придется привязать их (по столбцам или по строкам) до того, как установить класс и выделить. – Arun

-4

Это очень просто. В этом случае преобразование CSV-файла, который R сохраняет в качестве фрейма данных.

housing_url <- "https://d396qusza40orc.cloudfront.net/getdata%2Fdata%2Fss06pid.csv" 
download.file(housing_url, destfile = "./housing.csv", method = "curl") 
require(data.table) 
DTableFile <- as.data.table(read.csv("./data/housing.csv")) 
Смежные вопросы