वेक्टर से कई मान कैसे हटाएं?


125

मेरे पास एक वेक्टर है जैसे: a = c(1:10)और मुझे कई मान निकालने होंगे, जैसे:2, 3, 5

वेक्टर में उन संख्याओं (वे वेक्टर में स्थिति नहीं हैं ) को कैसे हटाएं ?

फिलहाल मैं वेक्टर को लूप करता हूं और कुछ ऐसा करता हूं:

a[!a=NUMBER_TO_REMOVE]

लेकिन मुझे लगता है कि एक फ़ंक्शन है जो इसे स्वचालित रूप से करता है।

जवाबों:


192

%in%ऑपरेटर आपको बताता है जो तत्वों को दूर करने के numers में से एक हैं:

> a <- sample (1 : 10)
> remove <- c (2, 3, 5)
> a
 [1] 10  5  2  7  1  6  3  4  8  9
> a %in% remove
 [1] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
> a [! a %in% remove]
 [1] 10  7  1  6  4  8  9

ध्यान दें कि यह चुपचाप अतुल्य वस्तुओं (जैसे NAया Inf)साथ में (जब तक यह aसूचीबद्ध नहीं है, तब तक डुप्लिकेट मान रखेगा) को हटा देगा remove

  • यदि aइसमें अतुलनीय सामग्री हो सकती है, लेकिन removeहम इसका उपयोग नहीं कर सकते हैं match, तो इसे 0गैर-मैचों और अतुलनीयों के लिए वापस जाने के लिए कह सकते हैं ( %in%यह एक उत्कृष्ट शॉर्टकट है match):

    > a <- c (a, NA, Inf)
    > a
     [1]  10   5   2   7   1   6   3   4   8   9  NA Inf
    > match (a, remove, nomatch = 0L, incomparables = 0L)
     [1] 0 3 1 0 0 0 2 0 0 0 0 0
    > a [match (a, remove, nomatch = 0L, incomparables = 0L) == 0L]
    [1]  10   7   1   6   4   8   9  NA Inf

    incomparables = 0नहीं है जरूरत incomparables वैसे भी मेल नहीं खाएगा के रूप में, लेकिन मैं इसे पठनीयता के कारण शामिल था।
    यह है, btw।, setdiffआंतरिक रूप से क्या करता है (लेकिन बिना uniqueडुप्लिकेट को फेंकने के लिए aजिसमें नहीं हैं remove)।

  • यदि removeअतुलनीय हैं, तो आपको उनके लिए व्यक्तिगत रूप से जांच करनी होगी, जैसे

    if (any (is.na (remove))) 
      a <- a [! is.na (a)]

    (यह अंतर नहीं करता है NA, NaNलेकिन आर मैनुअल वैसे भी चेतावनी देता है कि किसी को उन दोनों के बीच अंतर होने पर भरोसा नहीं करना चाहिए)

    के लिए Inf/ -Infआपको दोनों की जांच करनी होगी signऔरis.finite


1
setdiffबेहतर है, क्योंकि यह एक ऑपरेशन में सब कुछ करता है, और केवल एक बार संशोधित वेक्टर का संदर्भ देता है।
ओलेक्सा

1
@ ओलेक्सा: सेट अंतर हमेशा एक वेक्टर से संख्याओं के दिए गए सेट की सभी घटनाओं को हटाने के समान नहीं होता है: यह डुप्लिकेट को aउस में भी हटा देगा remove। यदि यह कोई समस्या नहीं है, तो आप भी उपयोग कर सकते हैं setdiffsetdiff, btw, का उपयोग करता matchहै जिसके %in%लिए एक शॉर्टकट है।
एसक्यूएल

97

आप उपयोग कर सकते हैं setdiff

दिया हुआ

a <- sample(1:10)
remove <- c(2, 3, 5)

फिर

> a
 [1] 10  8  9  1  3  4  6  7  2  5
> setdiff(a, remove)
[1] 10  8  9  1  4  6  7

1
बहुत उपयोगी है जब aदूसरे फ़ंक्शन का परिणाम होता है तो आप 3 के बजाय एक लाइन में चीजों को कर सकते हैं और एक अस्थायी चर
jf328

14
यह %in%समाधान से भिन्न परिणाम उत्पन्न करेगा यदि इनपुट वेक्टर में डुप्लिकेट शामिल हैं (जिस स्थिति setdiffमें केवल अद्वितीय सेट लौटाएगा , अर्थात बिना डुप्लिकेट के)
ताल

2
@docendodiscimus: fsetdiffके data.tableपैकेज एक है allझंडा (डिफ़ॉल्ट एफ) कि इनपुट वेक्टर में डुप्लिकेट रखने के लिए अनुमति देता है।
Juergen

9

आप इसे निम्नानुसार कर सकते हैं:

> x<-c(2, 4, 6, 9, 10) # the list
> y<-c(4, 9, 10) # values to be removed

> idx = which(x %in% y ) # Positions of the values of y in x
> idx
[1] 2 4 5
> x = x[-idx] # Remove those values using their position and "-" operator
> x
[1] 2 6

कुछ ही समय

> x = x[ - which(x %in% y)]

1
क्या आप अपने उदाहरण में एक सूची बुला रहे हैं एक वेक्टर है, है ना?
पैट्रिक

हां मेरा मतलब वेक्टर से है। टिप्पणी के लिए धन्यवाद।
21

इसमें कोई जरूरत नहीं whichहै। यह मूल रूप से @cbeleites उत्तर के समान है।
डेविड ऐरनबर्ग

हां यह समान है, लेकिन कुछ बिंदुओं में अलग है। whichTRUE मानों का अनुक्रमणिका देता है। इसलिए माइनस साइन का उपयोग "इन इंडेक्स के अलावा अन्य इंडेक्स" को कहने के लिए किया जा सकता है। यह whichभी अधिक पठनीय है क्योंकि यह प्राकृतिक भाषा के करीब है।
ykpemre 12

4

के बजाय

x <- x[! x %in% c(2,3,5)]

पैकेज का उपयोग कर purrrऔर magrittr, आप कर सकते हैं:

your_vector %<>% discard(~ .x %in% c(2,3,5))

यह subsetकेवल एक बार वेक्टर नाम का उपयोग करके टिंग के लिए अनुमति देता है । और आप इसे पाइपों में इस्तेमाल कर सकते हैं :)


क्या आप चर नाम लंबाई के बारे में अपना अंतिम विवरण बता सकते हैं? आप ऐसा क्यों नहीं करते? दूसरे तरीके से बेहतर क्यों है? या, उस अनुच्छेद को हटा दें क्योंकि वह मुख्य मुद्दे / प्रश्न से संबंधित नहीं है।
कृत्तृोप

2

पहले हम एक नए ऑपरेटर को परिभाषित कर सकते हैं,

"%ni%" = Negate( "%in%" )

फिर, एक्स की तरह नहीं हटा में

x <- 1:10
remove <- c(2,3,5)
x <- x[ x %ni% remove ]

या हटाने के लिए क्यों जाएं, सीधे जाएं

x <- x[ x %ni% c(2,3,5)]

3
प्रश्न विशेष रूप से कहता है कि 2, 3 और 5 वेक्टर में स्थिति नहीं हैं।
ब्लेकॉफ्ट

1

अपडेट करें:

उपरोक्त सभी उत्तर बार-बार दिए गए मानों के लिए काम नहीं करेंगे, @ BenBolker का उत्तर duplicated()यह है कि यह हल करता है:

full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]

मूल उत्तर: यहां मैं इसके लिए एक छोटा सा कार्य लिखता हूं:

exclude_val<-function(full_vector,searched_vector){

      found=c()

      for(i in full_vector){  

        if(any(is.element(searched_vector,i))){
          searched_vector[(which(searched_vector==i))[1]]=NA
        }
        else{
          found=c(found,i)
        }
    }

    return(found)
}

तो, चलो कहते हैं full_vector=c(1,2,3,4,1)औरsearched_vector=c(1,2,3)

exclude_val(full_vector,searched_vector)(4,1) वापस आएगा, हालांकि उपरोक्त उत्तर बस वापस आ जाएंगे (4)


1
किस बारे में full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]?
बेन बोल्कर

@BenBolker आह मुझे नहीं पता था कि "डुप्लिकेटेड" विधेय: (अब क्या होगा, मैं अपना उत्तर हटा दूंगा या इसे केवल आपके बजाय दिखाने के लिए बदल दूंगा?
3zgür

@BenBolker, आपका समाधान गलत है; बस कोशिश करें: full_vector = c(1,1,1,2,3); searched_vector = c(1,1,3);- जो 1, 1, 2सही उत्तर के बजाय पैदा करता है 1, 2
fnl

बस दोहराया मूल्यों के लिए एक संभव, सही समाधान जोड़ने के लिए:removeif <- function(from, where) { for (i in where) if (i %in% from) {from = from[-match(i, from)]}; from}
fnl

1
q <- c(1,1,2,2,3,3,3,4,4,5,5,7,7)
rm <- q[11]
remove(rm)
q
q[13] = NaN
q
q %in% 7

यह एक वेक्टर में 13 को एक संख्या (NAN) नहीं के रूप में सेट करता है, यह गलत निष्कासन (q [c (11,12,13))] दिखाता है यदि आप यह कोशिश करते हैं कि आप देखेंगे कि हटाएं फ़ंक्शन वेक्टर नंबर पर काम नहीं करता है। आप पूरे वेक्टर को हटा देते हैं लेकिन शायद एक भी तत्व नहीं है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.