Как удалить несколько значений из вектора?
У меня есть вектор: 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