If you need to remove multiple elements from the vector, the std::remove will copy each, not removed element only once to its final location, while the vector::erase approach would move all of the elements from the position to the end multiple times.
All the elements of the vector are removed using clear() function. erase() function, on the other hand, is used to remove specific elements from the container or a range of elements from the container, thus reducing its size by the number of elements removed.
Declare a boolean vector that has TRUE at all the positions you want to retain and FALSE at those you want to delete. Suppose that vector is y. Then, x[y] will give you the requires output.
To delete an item at specific index from R Vector, pass the negated index as a vector in square brackets after the vector. We can also delete multiple items from a vector, based on index.
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
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
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)]
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 :)
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)]
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With