2012-12-11 12 views
8

मान लीजिए मैं नाम के साथ दो सूचियों है के साथ विलय सूचियों,आर - अधिलेखित और प्रत्यावर्तन

a = list(a=1, b=2, c=list(d=1, e=2), d=list(a=1, b=2)) 
b = list(a=2, c=list(e=1, f=2), d=3, e=2) 

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

$a 
[1] 2 

$b 
[1] 2 

$c 
$c$d 
[1] 1 

$c$e 
[1] 1 

$c$f 
[1] 2 

$d 
[1] 3 

$e 
[1] 2 

कोई संकेत?

उत्तर

9

मुझे लगता है कि आपको अपना खुद का रिकर्सिव फ़ंक्शन यहां लिखना होगा।

एक फ़ंक्शन जो दो सूचियों में लेता है, list1 और list2। हैं:

  • list1[[name]] मौजूद है, लेकिन नहीं list2[[name]], list1[[name]] का उपयोग करें;
  • list1[[name]] मौजूद है साथ ही list2[[name]] और दोनों सूचियां नहीं हैं, list2[[name]] का उपयोग करें;
  • अन्यथा, नई सूचियों के रूप में list1[[name]] और list2[[name]] के साथ पुन: साझा करें।

कुछ की तरह:

myMerge <- function (list1, list2) { 
    allNames <- unique(c(names(list1), names(list2))) 
    merged <- list1 # we will copy over/replace values from list2 as necessary 
    for (x in allNames) { 
     # convenience 
     a <- list1[[x]] 
     b <- list2[[x]] 
     if (is.null(a)) { 
      # only exists in list2, copy over 
      merged[[x]] <- b 
     } else if (is.list(a) && is.list(b)) { 
      # recurse 
      merged[[x]] <- myMerge(a, b) 
     } else if (!is.null(b)) { 
      # replace the list1 value with the list2 value (if it exists) 
      merged[[x]] <- b 
     } 
    } 
    return(merged) 
} 

चेतावनियां - अपनी सूची मर्ज करने अगर अजीब हैं, तो आप अजीब उत्पादन मिल सकता है। उदाहरण के लिए:

a <- list(a=list(a=1, b=2), b=3) 
b <- list(a=2) 

फिर अपने मर्ज किए गए सूची a=2, b=3 है। ऐसा इसलिए है क्योंकि b$a से मान a$a से मान ओवरराइड करता है, भले ही a$a एक सूची है (आपने यह निर्दिष्ट नहीं किया था कि यह क्या होगा यदि यह मामला था)। हालांकि इस तरह के मामलों को संभालने के लिए myMerge को संशोधित करना काफी आसान है। बस याद रखें - यह जांचने के लिए is.list का उपयोग करें कि यह एक सूची है, और is.null(myList$a) यह देखने के लिए कि प्रविष्टि a सूची myList में मौजूद है या नहीं।

merge.lists <- function(a, b) { 
    a.names <- names(a) 
    b.names <- names(b) 
    m.names <- sort(unique(c(a.names, b.names))) 
    sapply(m.names, function(i) { 
     if (is.list(a[[i]]) & is.list(b[[i]])) merge.lists(a[[i]], b[[i]]) 
     else if (i %in% b.names) b[[i]] 
     else a[[i]] 
    }, simplify = FALSE) 
} 
+0

देता है मैं अनिश्चित हूं कि अगर यह का उपयोग कर vectorised किया जा सकता है 'vapply'/समान, जबकि अभी भी आंतरिक संरचना रखते हुए। –

+0

यह बढ़िया है! वास्तव में मुझे क्या चाहिए। बीटीडब्लू, मेरे उदाहरण में 'अजीब' सूची प्रविष्टि थी (दोनों सूचियों में 'डी')। – zeeMonkeez

+0

यदि आप 'if (n.null (a) &&! Is.null (b) && xor (is.list (a), is.list (b)) जोड़ते हैं) { विलय [[x]] <- सी (ए, बी) } ' उस वक्तव्य की शुरुआत में, आप उस किनारे के मामले के लिए खाते हैं, स्वीकार्य रूप से ओवरराइट खोना। –

6

मैं एक कस्टम समारोह यहां आवश्यक है यदि ऐसा है तो यकीन नहीं है:


यहाँ "vectorized" sapply का उपयोग कर संस्करण है। इस सटीक ऑपरेशन को करने के लिए utils::modifyList() फ़ंक्शन है! अधिक जानकारी के लिए modifyList देखें।

a <- list(a=1, b=2, c=list(d=1, e=2), d=list(a=1, b=2)) 
b <- list(a=2, c=list(e=1, f=2), d=3, e=2) 

modifyList(a, b) # updates(modifies) 'a' with 'b' 

निम्नलिखित में से कौन

$a 
[1] 2 

$b 
[1] 2 

$c 
$c$d 
[1] 1 

$c$e 
[1] 1 

$c$f 
[1] 2 

$d 
[1] 3 

$e 
[1] 2 
+0

मुझे यकीन नहीं है कि इसे सही उत्तर क्यों नहीं माना जाता है – rmg

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