2013-08-27 15 views
7
के स्थान पर निर्भर

पर विचार करें इसdo.call rbind एनए

do.call(rbind, list(data.table(x=1, b='x'),data.table(x=1, b=NA))) 

रिटर्न

x b 
1: 1 x 
2: 1 NA 

लेकिन

do.call(rbind, list(data.table(x=1, b=NA),data.table(x=1, b='x'))) 

रिटर्न

x b 
1: 1 NA 
2: 1 NA 

सूची की सामग्री को पुन: व्यवस्थित किए बिना, मैं पहले व्यवहार को कैसे मजबूर कर सकता हूं?

मैड्रिडस नौकरियों में डेटा तालिका वास्तव में वास्तव में तेज़ है (डेटा नोड्स में डेटाटेबल ~ 10 * 3 एमएम बार कॉल करना, डेटा तालिका डेटा फ्रेम से कई गुना तेज है, इसलिए मैं इसे काम करना चाहता हूं ...) सादर सप्तर्षि

+1

मैं इस अनुमान लगा रहा हूँ इसलिए होता है क्योंकि 'NA' तार्किक है और' as.logical ('एक्स') = NA', इसलिए जब 'rbind' फैसला करता है कि उस स्तंभ तार्किक है (इसके पहले तर्क के आधार पर) , यह मिलान करने के लिए बाद के आइटम coerces। 'do.call (rbind, list (data.table (x = 1, b = as (NA, 'character')), data.table (x = 1, b = 'x')) '' काम करता है ... – Frank

+3

वैसे, 'rbindlist' नामक डेटा.tables के लिए "अनुकूलित' do.call (rbind, ...)' "है। इस साइट पर इसके बारे में कुछ क्यू हैं, उदाहरण के लिए, http://stackoverflow.com/questions/15673550/why-is-rbindlist-better-than-rbind/15673654#15673654 – Frank

+1

@ फ्रैंक - बहुत उपयोगी टिप्पणियां। मैंने अपने उत्तर में 'rbindlist' का संदर्भ जोड़ा है। –

उत्तर

8

जैसा कि फ्रैंक द्वारा उल्लेख किया गया है, समस्या यह है कि NA के कई अलग-अलग प्रकार हैं (कुछ हद तक अदृश्य)। कमांड लाइन पर NA टाइप करते समय उत्पादित उत्पाद "logical" है, लेकिन NA_integer_, NA_real_, NA_character_, और NA_complex_ भी हैं।

अपने पहले उदाहरण में, प्रारंभिक data.table स्तंभ b "चरित्र" के वर्ग सेट, और दूसरा data.table में NA तो एक NA_character_ लिए मजबूर कर रहा है। दूसरे उदाहरण में, हालांकि, NA पहले data.table में कॉलम b की कक्षा को "लॉजिकल" पर सेट करता है, और जब दूसरे डेटाटेबल में एक ही कॉलम को "लॉजिकल" के लिए मजबूर किया जाता है, तो इसे लॉजिकल एनए में परिवर्तित कर दिया जाता है। (as.logical("x") देखें क्यों देखें।)

यह सब काफी जटिल है (कम से कम स्पष्ट करने के लिए), लेकिन एक उचित सरल समाधान है। बस 1-पंक्ति टेम्पलेट data.table बनाएं, और इसे data.table की प्रत्येक सूची में प्रीपेड करें, आप rbind() चाहते हैं। यह data.table पर rbind() पर दी गई सूची में इसका पालन करने के बावजूद, प्रत्येक स्तंभ के वर्ग को प्रत्येक कॉलम की श्रेणी स्थापित करेगा, और किसी अन्य चीज को एक साथ बांधने के बाद इसे छंटनी की जा सकती है।

library(data.table)  

## The two lists of data.tables from the OP 
A <- list(data.table(x=1, b='x'),data.table(x=1, b=NA)) 
B <- list(data.table(x=1, b=NA),data.table(x=1, b='x')) 

## A 1-row template, used to set the column types (and then removed) 
DT <- data.table(x=numeric(1), b=character(1)) 

## Test it out 
do.call(rbind, c(list(DT), A))[-1,] 
# x b 
# 1: 1 x 
# 2: 1 NA 
do.call(rbind, c(list(DT), B))[-1,] 
# x b 
# 1: 1 NA 
# 2: 1 x 

## Finally, as _also_ noted by Frank, rbindlist will likely be more efficient 
rbindlist(c(list(DT), B)[-1,] 
+0

धन्यवाद। इच्छा है कि यह डेटा के रूप में सरल था। फ्रेम – Sapsi

+1

बेशक यह संभवतः सभी मामलों में 'rbind'ing को धीमा कर देगा। दूसरी तरफ, 'rbindlist()' में दूसरे 'colClasses' तर्क को जोड़ने में कठिनाई नहीं हो सकती है, जिससे उपयोगकर्ता कक्षा के नामों के वर्ण वेक्टर या वांछित कक्षाओं के तत्वों के साथ एक सूची में प्रवेश कर सकते हैं। –

संबंधित मुद्दे