आर

2010-07-06 6 views
14

में एक तालिका को अद्यतन करने के लिए विलय() का उपयोग कैसे करें मैं डेटाबेस को अद्यतन करने के लिए merge() का उपयोग करने का तरीका जानने का प्रयास कर रहा हूं।आर

यहां एक उदाहरण है।

index value 
1  c 200 
2  d 201 
: उदाहरण के लिए foo

foo <- data.frame(index=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA)) 

डेटा फ्रेम कौन सा निम्न मान

index value 
1  a 100 
2  b 101 
3  c NA 
4  d NA 

और डेटा फ्रेम bar

bar <- data.frame(index=c('c', 'd'), value=c(200, 201)) 

निम्नलिखित में से कौन मान हैं है ले लो

जब मैं c और d

merge(foo, bar, by='index', all=T) 

यह इस उत्पादन में जो परिणाम के लिए मान अद्यतन करने के लिए निम्नलिखित merge() समारोह चलाएँ:

index value.x value.y 
1  a  100  NA 
2  b  101  NA 
3  c  NA  200 
4  d  NA  201 

मैं merge() के उत्पादन में करना चाहते हैं के निर्माण से बचने के लिए , इस विशिष्ट उदाहरण में, value.x और value.y पर, लेकिन केवल value के मूल स्तंभ को बनाए रखें क्या यह करने का एक आसान तरीका है?

+0

क्या परिणाम नहीं nulls के मामले में किया जाना चाहिए? –

+1

क्या आपको कभी इस प्रश्न का उत्तर मिला? मैं इसी समस्या के लिए एक समाधान की तलाश में हूं। – Gandalf

+0

मुझे आश्चर्य है कि विलय क्यों नहीं है, एक 'ओवरराइट = TRUE' पैरामीटर कहें जो 'by' प्रदान किया जाता है। जब भी आप विलय को फिर से शुरू करना चाहते हैं, तो मैन्युअल रूप से स्तंभों को हटाने के लिए यह असभ्य है। – Valentas

उत्तर

7

merge() हमेशा कॉलम को एक साथ बांधता है? replace() काम करता है?

foo$value <- replace(foo$value, foo$index %in% bar$index, bar$value) 

या match() तो आदेश मायने रखती है

foo$value[match(bar$index, foo$index)] <- bar$value 
+1

'प्रतिस्थापन()' का उपयोग करने के साथ एक शिकन यह है कि यदि 'बार' में ऑर्डरिंग 'foo' जैसा नहीं है, तो यह ठीक से काम नहीं करेगा। उदाहरण के लिए, यदि आप उपरोक्त उदाहरण को 'बार <- बार [सी (2,1),] के बाद चलाने का प्रयास करते हैं, तो अंतिम परिणाम सही नहीं होता है। – andrewj

+0

आप सही हैं मिलान() के बारे में कैसे? – apeescape

+0

से ऊपर संपादित हां, 'मिलान() 'मेरे उदाहरण के लिए काम करता है। हकीकत में, यह पता चला है कि मेरा वास्तविक उपयोग मामला अधिक जटिल है, जहां मैं कई कॉलमों से मेल खाना चाहता हूं न केवल एक साधारण वेक्टर। मुझे नहीं लगता कि 'मिलान()' काम करता है जब आप डेटाफ्रेम के एकाधिक कॉलम से मेल खाना चाहते हैं। – andrewj

0

merge() केवल नए डेटा में विलीन हो जाती है। उदाहरण के लिए, यदि आपके पास कुछ शहरों के लिए औसत आय का डेटा सेट था, और उन शहरों की आबादी का एक अलग डेटा सेट था, तो आप डेटा के एक सेट में दूसरे में विलय करने के लिए merge() का उपयोग करेंगे।

एपेस्केप की तरह, replace() शायद आप जो चाहते हैं।

2

मैं लाइब्रेरी sqldf और आर एकीकृत SQLite-डेटाबेस का उपयोग कर एक एसक्यूएल-समाधान प्रस्तुत करना भी चाहूंगा। मुझे एसक्यूएल की सादगी, सटीकता और शक्ति पसंद है।
सटीकता: चूंकि मैं डेटा = फ्रेम (foo.id = bar.id) के आदेश पर विचार किए बिना मैं किस ऑब्जेक्ट = पंक्तियों को बदलना चाहता हूं, ठीक से परिभाषित कर सकता हूं।
पावर: एसईटी के बाद और कहां (तीसरी पंक्ति) में मैं उन सभी स्थितियों को परिभाषित कर सकता हूं जिन्हें मैं अपडेट करना चाहता हूं।
सरलता: सिंटैक्स वैक्टर, मैट्रिक्स या डेटाफ्रेम में इंडेक्स का उपयोग करने से अधिक पठनीय है।

library(sqldf) 

# I changed index to id since index does not work. 
# Obviously index is a key word in sqlite. 

(foo <- data.frame(id=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA))) 
(bar <- data.frame(id=c('c', 'd'), value=c(200, 201))) 

sqldf(c(paste("UPDATE foo" 
      ," SET value = (SELECT bar.value FROM bar WHERE foo.id = bar.id)" 
      ," WHERE value IS NULL" 
      ) 
     , " SELECT * FROM main.foo" 
    ) 
) 

id value 
1 a 100 
2 b 101 
3 c 200 
4 d 201 

इसी तरह के मुद्दों देता है कौन सा:
r equivalent of sql update?
R sqlite: update with two tables

+2

एसक्यूएल कथन कई लाइनों पर चला सकता है इसलिए 'पेस्ट' की आवश्यकता नहीं है। –

+0

@Grothendieck इस जानकारी के लिए धन्यवाद। – giordano

0

एक और दृष्टिकोण हो सकता है:

  1. निकालें पहली डेटा फ्रैम से NAS

  2. उपयोग बजाय मर्ज का उपयोग करने का डेटा संलग्न करने के लिए rbind:

    foo <- data.frame(index=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA)) 
    bar <- data.frame(index=c('c', 'd'), value=c(200, 201)) 
    

    (1) का उपयोग करें:

ये मूल दो डेटा फ्रेम हैं एनएएस को हटाने के लिए is.na की अस्वीकृति:

foo_new <- foo[!is.na(foo$value),] 

(2) डेटा फ्रेम बांधें और आपको मिल जाएगा इस सवाल का जवाब आप के लिए

new_df <- rbind(foo_new,bar) 

      new_df 
      index value 
      1  a 100 
      2  b 101 
      3  c 200 
      4  d 201 
0

देख रहे थे मुझे लगता है कि सबसे आसान तरीका "निशान" मूल्य जो अद्यतन मर्ज करने से पहले होने की जरूरत है।

bar$update <- TRUE 
foo <- merge(foo, bar, by='index', all=T, suffixes=c("",".update")) 
foo[!is.na(foo$update),]$value <- foo[!is.na(foo$update),]$value.update 
foo$value.update <- NULL 
foo$update <- NULL 

यह तेजी से 'data.table' का उपयोग किया जाएगा

library(data.table) 
foo <- as.data.table(foo) 
bar <- as.data.table(bar) 
bar[, update:=TRUE] 
foo <- merge(foo, bar, by='index', all=T, suffixes=c("",".update")) 
foo[!is.na(update),value:=value.update] 
foo[, c("value.update","update"):=NULL] 
foo 

    index value 
1:  a 100 
2:  b 101 
3:  c 200 
4:  d 201