कॉपी के बिना एक डेटा फ्रेम को डेटाटेबल में बदलें


81

मेरे पास एक बड़ा डेटा फ्रेम (कई जीबी के क्रम में) है जिसे मैं एक में बदलना चाहता हूं 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

जवाबों:


93

यह v1.9.0 + से उपलब्ध है । से समाचार :

o इस SO पोस्ट के बाद , एक फ़ंक्शन 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*

पुराने (अब पुराने) उत्तर के लिए इतिहास देखें।


@ अरुण: विस्तृत उत्तर के लिए धन्यवाद। मैं वास्तव में पूछ रहा था कि डेटा फ़्रेम को डेटाटेबल में कैसे परिवर्तित किया जाए, लेकिन टॉय उदाहरण बनाने में मैला था, मैं इसे डेटा फ़्रेम बनाने के लिए अपने प्रश्न को अपडेट करूंगा। क्या एक ही विचार तब डेटा फ्रेम के लिए काम करेगा, उदाहरण के लिए, पहले दो सेटटर से छुटकारा पाने के बाद से डेटा फ्रेम पहले से ही इन और बाकी को बनाए रखता है?
ytsaig

@YT, अगर आपका मतलब "data.able" से "data.table" हो रहा है, तो निश्चित रूप से आप जो कहते हैं वह सही है। यदि आपके पास data.frames की सूची है, तो आपको कक्षा सेट करने और आवंटित करने से पहले उन्हें (स्तंभ या पंक्ति-वार) बाँधना होगा।
अरुण

@ अरुण, मेरा मतलब था कि पूर्व, एक डेटा फ्रेम के लिए एक डेटा। टायलेट, मैंने प्रश्न को संपादित किया उम्मीद है कि यह बेहतर तरीके से प्रतिबिंबित करेगा। एक चतुर समाधान के लिए फिर से धन्यवाद, मैं इस उत्तर को स्वीकार कर सकता हूं या यदि आप इसे संशोधित प्रश्न से मिलान करना चाहते हैं तो प्रतीक्षा करें।
यत्सिग

2
हो सकता है कि इस पोस्ट मैथ्यू से मदद मिलेगी के बारे में अधिक प्रकाश डाला truelength
अरुण

3
@eddi R2.14.0 से पहले, truelengthआर के वेक्टर हेडर के सदस्य को आर। द्वारा सी में आरंभीकृत नहीं किया गया था। यदि आप एक वैरिएबल को इनिशियलाइज़ नहीं करते हैं तो इसमें अपरिभाषित सामग्री होती है (जो कुछ भी पहले रैम के उस हिस्से में होता है)। data.table()और इसी तरह के रचनाकारों को प्री आर 2.14.0 के साथ संगतता के लिए truelengthकॉल करने से पहले 0 से प्रारंभ करें alloc.col। एक इनपुट के रूप में alloc.colदिखता है truelength(0 का अर्थ ट्रुएल्रोट्रिक्स == लंबाई है)। एक बिंदु पर मुझे लगा कि डेटाटेबल को इस वजह से R> = 2.14.0 पर निर्भर रहना होगा, लेकिन इसे R> = 2.12.0 रखने में कामयाब रहे। मैं CRAN के लिए प्रत्येक रिलीज से पहले R2.12.0 के साथ परीक्षण करता हूं।
मैट डॉवले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.