2016-02-03 16 views
11

भरने वाले मूल्य के साथ दो डेटा तालिकाओं (डीटी 1, डीटी 2) पर बाएं बाहरी जुड़ने का सबसे आसान तरीका क्या है (या कुछ अन्य मूल्य) बाएं डेटा तालिका में मान्य NA मानों को ओवरराइट किए बिना एनए (डिफ़ॉल्ट) के बजाय?आर बाएं बाहरी 0 के साथ जुड़ें एनए के बजाय भरें बाएं तालिका में वैध एनए की रक्षा करते समय

ऐसे this thread में के रूप में एक आम जवाब है, बाईं बाहरी करना है या तो dplyr::left_join या data.table::merge या data.table के DT2 साथ शामिल होने के [DT1] बंद स्तंभ ब्रैकेट वाक्य रचना, बस में 0 द्वारा सभी NA मूल्यों की जगह एक दूसरे चरण के बाद शामिल डेटा तालिका। उदाहरण के लिए:

library(data.table); 
dt1 <- data.table(x=c('a', 'b', 'c', 'd', 'e'), y=c(NA, 'w', NA, 'y', 'z')); 
dt2 <- data.table(x=c('a', 'b', 'c'), new_col=c(1,2,3)); 
setkey(dt1, x); 
setkey(dt2, x); 
merged_tables <- dt2[dt1]; 
merged_tables[is.na(merged_tables)] <- 0; 

यह दृष्टिकोण जरूरी हो जाती है dt1 में कोई मान्य एनए मूल्यों को संरक्षित किया जा करने की जरूरत है कि देखते हैं कि। फिर भी, जैसा कि आप ऊपर के उदाहरण में देख सकते हैं, परिणाम हैं:

x new_col y 
1: a  1 0 
2: b  2 w 
3: c  3 0 
4: d  0 y 
5: e  0 z 

लेकिन वांछित परिणाम इस प्रकार हैं: इस तरह के एक तुच्छ मामले में

x new_col y 
1: a  1 NA 
2: b  2 w 
3: c  3 NA 
4: d  0 y 
5: e  0 z 

, data.table उपयोग करने के बजाय सभी तत्वों वाक्य रचना की जगह जैसा कि ऊपर, बस new_col में एनए मूल्यों बदला जा सकता है:

library(dplyr); 
merged_tables <- mutate(merged_tables, new_col = ifelse(is.na(new_col), 0, new_col)); 

हालांकि, इस पद्धति बहुत बड़े डेटा सेट जहां दर्जनों या सैकड़ों के लिए व्यावहारिक नहीं है नए कॉलम मर्ज किए जाते हैं, कभी-कभी गतिशील रूप से बनाए गए कॉलम नामों के साथ। भले ही कॉलम नाम सभी समय से पहले ज्ञात थे, फिर भी सभी नए कॉलमों को सूचीबद्ध करने के लिए बहुत बदसूरत है और प्रत्येक पर एक उत्परिवर्ती शैली बदलती है।

एक बेहतर तरीका होना चाहिए? dplyr::left_join, data.table::merge, या data.table के ब्रैकेट के सिंटैक्स को आसानी से उपयोगकर्ता को fill मान को निर्दिष्ट करने की अनुमति देने के लिए समस्या को हल किया जाएगा। की तरह कुछ:

merged_tables <- data.table::merge(dt1, dt2, by="x", all.x=TRUE, fill=0); 

data.table के dcast समारोह उपयोगकर्ता fill मूल्य निर्दिष्ट कर सकते हैं, तो मैं समझ यह है कि मैं सिर्फ के बारे में सोच नहीं कर रहा हूँ करने के लिए एक आसान तरीका होना चाहिए।

सुझाव?

संपादित करें: @jangorecki ने टिप्पणियों में बताया कि data.table GitHug page पर वर्तमान में एक फीचर अनुरोध है जो मैंने अभी उल्लेख किया है, nomatch=0 वाक्यविन्यास को अपडेट करना। data.table की अगली रिलीज में होना चाहिए।

+1

(समाधान tidyr और dplyr की आवश्यकता है) अपने 'merge' के अंत में या बाहरी उपयोग करके शामिल' [..., nomatch = एनए] 'श्रृंखला data.table क्वेरी' मर्ज() [is.na (कोला), कोल: = 0] '। एक खुला एफआर है इसलिए 'नामांकन' तर्क मनमाना मूल्यों को संभाल सकता है, वर्तमान में बाहरी शामिल होने के लिए यह केवल 'एनए' का उपयोग कर सकता है। – jangorecki

+0

मुझे खेद है, लेकिन मुझे आपके उत्तर को समझने में परेशानी हो रही है। 'कोल' कहां से आता है? यह सुनकर खुशी हुई कि एक खुला फीचर अनुरोध है। मैं इसे अपना +1 जोड़ दूंगा। –

+0

'col' सिर्फ एक कॉलम है जिस पर शामिल किया जा रहा है – jangorecki

उत्तर

2

क्या आप केवल नए कॉलम के संदर्भ में कॉलम इंडेक्स का उपयोग कर सकते हैं, जैसे left_join वे सभी परिणामस्वरूप डेटा.फ्रेम के दाईं ओर होंगे? यहाँ यह dplyr में होगा:

dt1 <- data.frame(x = c('a', 'b', 'c', 'd', 'e'), 
        y = c(NA, 'w', NA, 'y', 'z'), 
        stringsAsFactors = FALSE) 
dt2 <- data.frame(x = c('a', 'b', 'c'), 
        new_col = c(1,2,3), 
        stringsAsFactors = FALSE) 

merged <- left_join(dt1, dt2) 
index_new_col <- (ncol(dt1) + 1):ncol(merged) 
merged[, index_new_col][is.na(merged[, index_new_col])] <- 0 

> merged 
    x y new_col 
1 a <NA>  1 
2 b w  2 
3 c <NA>  3 
4 d y  0 
5 e z  0 
+0

यह गारंटी है कि वे जिसके परिणामस्वरूप data.frame में हो जा रहे हैं सही पर अगर यह एक data.table है जब 'का उपयोग कर dplyr :: left_join' है? ध्यान दें कि 'data.table' उदाहरण में, कॉलम कुंजी कॉलम के दाईं ओर डाले गए थे, सभी मौजूदा' x' कॉलम के दाईं ओर नहीं। –

+1

'left_join' विश्वसनीय रूप से दाईं ओर दाईं ओर दूसरी तालिका से कॉलम रखता है। मैं नहीं जानता कि कैसे अपने विलय समारोह का उपयोग करते समय'data.table' आदेश कॉलम। मैं इस उदाहरण डब्ल्यू/'data.frame' वस्तुओं किया क्योंकि data.table पैकेज' [ 'मेरी अंतिम पंक्ति में है, लेकिन मैं एक ही स्तंभ आदेश प्राप्त जब मैं' दो 'left_join' data.table's अधिक भार था। मेरे उदाहरण में आखिरी पंक्ति चलाने के लिए डेटाटेबल को उतारने के अलावा, वस्तुओं को शामिल होने से पहले 'as_data_frame' के साथ जोड़ा जा सकता है - या जो कोई 'data.table' जानता है, वह उस अंतिम पंक्ति को काम करने के लिए अनुकूलित कर सकता है क्योंकि यह आधार आर में करता है –

+0

आपके उत्तर के लिए धन्यवाद। मैं बहुत बड़े डेटासेट पर काम कर रहा हूं इसलिए जब भी मैं विलय करता हूं (मैं कई करता हूं) डेटा डेटाटेबल और डेटा.फ्रेम के बीच स्विच करने के बारे में थोड़ा चिंतित हूं। मैं यह देखने के लिए कुछ प्रदर्शन परीक्षण करूंगा कि यह व्यवहार्य है या नहीं। 'Answeratch' के लिए नए विकल्पों के साथ' data.table' v1.9.8 जारी होने तक आपका उत्तर सबसे अच्छा हो सकता है। –

1

वर्तमान में स्पष्ट तरीका बस बीज के मूल्यों के साथ एक मध्यस्थ तालिका बाईं तालिका (DT1) में शामिल हो गए पर किया जाना है, DT2 की एक मर्ज श्रृंखला हो सकती है, एनए सेट 0 के मान, डीटी 1 के साथ मध्यस्थ तालिका मर्ज करें।data.table साथ पूरी तरह से किया जा सकता है और data.frame वाक्य रचना पर निर्भर नहीं करता है, और मध्यस्थ कदम सुनिश्चित करता है कि वहाँ कोई नहीं होगा कि nomatch एनए दूसरा मर्ज में परिणाम:

library(data.table); 
dt1 <- data.table(x=c('a', 'b', 'c', 'd', 'e'), y=c(NA, 'w', NA, 'y', 'z')); 
dt2 <- data.table(x=c('a', 'b', 'c'), new_col=c(1,2,3)); 
setkey(dt1, x); 
setkey(dt2, x); 
inter_table <- dt2[dt1[, list(x)]]; 
inter_table[is.na(inter_table)] <- 0; 
setkey(inter_table, x); 
merged <- inter_table[dt1]; 

> merged; 
    x new_col y 
1: a  1 NA 
2: b  2 w 
3: c  3 NA 
4: d  0 y 
5: e  0 z 

इस दृष्टिकोण का लाभ यह है कि यह नहीं करता है 'है टी दाईं ओर जोड़े गए नए कॉलम पर निर्भर करता है और data.table कुंजी गति गति अनुकूलन के अंदर रहता है। @ सैमफिरके का जवाब देना क्योंकि उनका समाधान भी काम करता है और अन्य संदर्भों में अधिक उपयोगी हो सकता है।

0

मैं dplyr साथ एक ही समस्या पर ठोकर खाई और एक छोटे से समारोह है कि मेरी समस्या हल लिखा था।

left_join0 <- function(x, y, fill = 0L){ 
    z <- left_join(x, y) 
    tmp <- setdiff(names(z), names(x)) 
    z <- replace_na(z, setNames(as.list(rep(fill, length(tmp))), tmp)) 
    z 
} 
संबंधित मुद्दे