Dail
Dail

Reputation: 4608

How to delete multiple values from a vector?

I have a vector like: a = c(1:10) and I need to remove multiple values, like: 2, 3, 5

How to delete those numbers (they are NOT the positions in the vector) in the vector?

at the moment i loop the vector and do something like:

a[!a=NUMBER_TO_REMOVE]

But I think there is a function that does it automatically.

Upvotes: 157

Views: 300035

Answers (9)

Armando Contestabile
Armando Contestabile

Reputation: 300

Try this function

seq.int.exclude <- function(excluded, ...) {
    x <- seq.int(...)
    return(x[!(x %in% excluded)])
}

Call examples:

seq.int.exclude(from = 10L, to = 20L, excluded = c(12L, 30L, 19L))
seq.int.exclude(from = 10L, to = 20L, excluded = 15L)

Upvotes: 1

krishan404
krishan404

Reputation: 111

instead of

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

using the packages purrr and magrittr, you can do:

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

this allows for subsetting using the vector name only once. And you can use it in pipes :)

Upvotes: 11

cbeleites
cbeleites

Reputation: 14093

The %in% operator tells you which elements are among the numers to remove:

> 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

Note that this will silently remove incomparables (stuff like NA or Inf) as well (while it will keep duplicate values in a as long as they are not listed in remove).

  • If a can contain incomparables, but remove will not, we can use match, telling it to return 0 for non-matches and incomparables (%in% is a conventient shortcut for 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 is not needed as incomparables will anyways not match, but I'd include it for the sake of readability.
    This is, btw., what setdiff does internally (but without the unique to throw away duplicates in a which are not in remove).

  • If remove contains incomparables, you'll have to check for them individually, e.g.

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

    (This does not distinguish NA from NaN but the R manual anyways warns that one should not rely on having a difference between them)

    For Inf/ -Inf you'll have to check both sign and is.finite

Upvotes: 229

Karolis Koncevičius
Karolis Koncevičius

Reputation: 9656

There is also subset which might be useful sometimes:

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

> subset(a, !(a %in% bad))
[1]  9  7 10  6  8  1  4

Upvotes: 3

Mahendra
Mahendra

Reputation: 19

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

This sets the 13 in a vector to not a number(NAN) it shows false remove(q[c(11,12,13)]) if you try this you will see that remove function don't work on vector number. you remove entire vector but maybe not a single element.

Upvotes: 1

TheMI
TheMI

Reputation: 1761

First we can define a new operator,

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

Then, its like x not in remove

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

or why to go for remove, go directly

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

Upvotes: 4

&#214;zg&#252;r
&#214;zg&#252;r

Reputation: 8247

UPDATE:

All of the above answers won't work for the repeated values, @BenBolker's answer using duplicated() predicate solves this:

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

Original Answer: here I write a little function for this:

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)
}

so, let's say full_vector=c(1,2,3,4,1) and searched_vector=c(1,2,3).

exclude_val(full_vector,searched_vector) will return (4,1), however above answers will return just (4).

Upvotes: 2

ibilgen
ibilgen

Reputation: 480

You can do it as follows:

> 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

Shortly

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

Upvotes: 10

Brian Diggs
Brian Diggs

Reputation: 58855

You can use setdiff.

Given

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

Then

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

Upvotes: 119

Related Questions