Как удалить несколько значений из вектора?

У меня есть вектор: a = c(1:10), и мне нужно удалить несколько значений, например: 2, 3, 5

Как удалить эти числа (они НЕ позиции в векторе) в векторе?

в данный момент я петлю вектор и делать что-то вроде:

a[!a=NUMBER_TO_REMOVE]

Но я думаю, что есть функция, которая делает это автоматически.

Ответ 1

Оператор %in% сообщает, какие элементы входят в число чисел для удаления:

> 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 не нужен, так как несравнимые в любом случае не будут совпадать, но я бы включил его для удобства чтения.
    Это, между прочим, то, что setdiff делает внутренне (но без unique чтобы выбрасывать дубликаты в a которые не находятся в remove).

  • Если remove содержит несравненные, вы должны проверить их по отдельности, например,

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

    (Это не отличает NA от NaN но руководство R в любом случае предупреждает, что не следует полагаться на разницу между ними)

    Для Inf/-Inf вы должны проверить оба sign и is.finite

Ответ 2

Вы можете использовать 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

Ответ 3

x <- list("a", "b", "c", "d", "e"); # example list

x[-2];       # without 2nd element

x[-c(2, 3, 5)]; # without 2nd,3rd,5th element

Ответ 4

Вы можете сделать это следующим образом:

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

Ответ 5

вместо

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

используя пакеты purrr и magrittr, вы можете сделать:

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

это позволяет использовать subset с использованием имени вектора только один раз. И вы можете использовать его в трубах :)

Ответ 6

Сначала мы можем определить новый оператор,

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

Тогда, как x не в удалении

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

или зачем идти на удаление, идите прямо

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

Ответ 7

UPDATE:

Все приведенные выше ответы не будут работать для повторяющихся значений, ответ @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).

Ответ 8

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), оно показывает false удалить (д [с (11,12,13)]) если вы попробуете это, вы увидите, что функция удаления не работает с номером вектора. вы удаляете весь вектор, но, возможно, не один элемент.

Ответ 9

Существует также subset которое иногда может быть полезно:

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

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