Как удалить несколько значений из вектора? - PullRequest
109 голосов
/ 12 марта 2012

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

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

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

a[!a=NUMBER_TO_REMOVE]

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

Ответы [ 8 ]

175 голосов
/ 12 марта 2012

Оператор %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

89 голосов
/ 26 июля 2012

Вы можете использовать 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
7 голосов
/ 19 сентября 2013

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

> 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)]
3 голосов
/ 29 октября 2016

вместо

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

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

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

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

2 голосов
/ 12 июня 2015

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

"%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)]
1 голос
/ 12 ноября 2016
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)])), если вы попытаетесь это сделать, вы увидите, что функция удаления неработа над векторным номером.Вы удаляете весь вектор, но, возможно, не один элемент.

1 голос
/ 03 апреля 2015

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

0 голосов
/ 09 октября 2018

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

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

> subset(a, !(a %in% bad))
[1]  9  7 10  6  8  1  4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...