2015-11-25 10 views
5

में हटाकर मैं within और rm का उपयोग करके किसी सूची से नामित घटक को निकालने का प्रयास कर रहा हूं। यह एक घटक के लिए काम करता है, लेकिन दो या अधिक के लिए नहीं। मैं पूरी तरह से परेशान हूँ।कई नामांकित सूची घटकों को()

उदाहरण के लिए - यह काम करता है

aa = list(a = 1:3, b = 2:5, cc = 1:5) 
within(aa, {rm(a)}) 

within से उत्पादन सिर्फ गैर हटा घटकों होगा।

बहरहाल, यह नहीं करता है:

aa = list(a = 1:3, b = 2:5, cc = 1:5) 
within(aa, {rm(a); rm(b)}) 

न तो करता है:

within(aa, {rm(a, b)}) 

within से उत्पादन वाले, मैं दूर करने के लिए कोशिश कर रहा हूँ NULL करने के लिए सेट के साथ सभी घटकों, होगा । क्यूं कर?

+0

'aa [' a '] <- NULL'? – etienne

+0

ठीक है, हाँ। लेकिन मैं इसे – martin

+0

के अंदर करने की कोशिश कर रहा हूं यह अजीब व्यवहार है! आप एक को हटा सकते हैं, लेकिन उसके बाद वे नल के रूप में रहते हैं - भले ही 3 से अधिक कॉलम हों। समान रूप से 'भीतर (aa, {"b" <- NULL; "a" <- NULL}) ' – jeremycg

उत्तर

4

पहले, निम्नलिखित पर ध्यान दें व्यवहार:

> aa = list(a = 1:3, b = 2:5, cc = 1:5) 
> 
> aa[c('a', 'b')] <- NULL 
> 
> aa 
# $cc 
# [1] 1 2 3 4 5 

> aa = list(a = 1:3, b = 2:5, cc = 1:5) 
> 
> aa[c('a', 'b')] <- list(NULL, NULL) 
> 
> aa 
# $a 
# NULL 
# 
# $b 
# NULL 
# 
# $cc 
# [1] 1 2 3 4 5 

अब within.list के लिए कोड को देखो:

within.list <- function (data, expr, ...) 
{ 
    parent <- parent.frame() 
    e <- evalq(environment(), data, parent) 
    eval(substitute(expr), e) 
    l <- as.list(e) 
    l <- l[!sapply(l, is.null)] 
    nD <- length(del <- setdiff(names(data), (nl <- names(l)))) 
    data[nl] <- l 
    if (nD) 
     data[del] <- if (nD == 1) NULL else vector("list", nD) 
    data 
} 

समारोह की अंतिम पंक्ति के बाद दूसरे स्थान पर विशेष रूप से देखो। यदि सूची में हटाए गए आइटमों की संख्या एक से अधिक है, तो फ़ंक्शन अनिवार्य रूप से aa[c('a', 'b')] <- list(NULL, NULL) पर कॉल कर रहा है, क्योंकि vector("list", 2) दो आइटम सूची बनाता है जहां प्रत्येक आइटम NULL है। जहां हम समारोह की अंतिम पंक्ति के बाद दूसरे स्थान से else बयान को दूर हम within के अपने संस्करण बना सकते हैं:

mywithin <- function (data, expr, ...) 
{ 
    parent <- parent.frame() 
    e <- evalq(environment(), data, parent) 
    eval(substitute(expr), e) 
    l <- as.list(e) 
    l <- l[!sapply(l, is.null)] 
    nD <- length(del <- setdiff(names(data), (nl <- names(l)))) 
    data[nl] <- l 
    if (nD) data[del] <- NULL 
    data 
} 

अब यह परीक्षण करते हैं:

> aa = list(a = 1:3, b = 2:5, cc = 1:5) 
> 
> mywithin(aa, rm(a, b)) 
# $cc 
# [1] 1 2 3 4 5 

अब यह काम करता है के रूप में उम्मीद!

+0

आह, हां के साथ काम करता है। स्रोत को देखने के लिए सोचना चाहिए था। बहुत सराहना! – martin

+0

यह बहुत साफ है, लेकिन आपको 'in.list' से अन्य खंड को हटाने की आवश्यकता क्यों है? और यह मानते हुए कि यह एक बग है, कृपया 'बेस :: भीतर' पर आर बग दर्ज करें – smci

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