Odpowiedzi:
%in%
Operator informuje, które elementy należą do numers do usunięcia:
> 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
Zauważ, że to po cichu usunie nieporównywalne elementy (takie jak NA
lub Inf)
również (podczas gdy zachowa zduplikowane wartości, a
o ile nie są wymienione remove
).
Jeśli a
może zawierać nieporównywalne, ale remove
nie będzie, możemy użyć match
, mówiąc mu, aby zwracał 0
po niedopasowania i nieporównywalne ( %in%
jest to wygodny skrót do 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
nie jest potrzebne, ponieważ elementy nieporównywalne i tak nie będą pasować, ale dołączyłbym to ze względu na czytelność.
To jest przy okazji, co setdiff
robi wewnętrznie (ale bez unique
wyrzucania duplikatów, w a
których nie ma remove
).
Jeśli remove
zawiera nieporównywalne elementy, będziesz musiał sprawdzić je indywidualnie, np
if (any (is.na (remove)))
a <- a [! is.na (a)]
(To nie odróżnia NA
od NaN
ale instrukcja R jakikolwiek ostrzega, że nie należy liczyć na o różnicę między nimi)
Dla Inf
/ -Inf
będziesz musiał sprawdzić zarówno sign
iis.finite
a
których również nie ma remove
. Jeśli to nie problem, możesz również użyć setdiff
. setdiff
, przy okazji, używa match
do którego %in%
jest skrót.
Możesz użyć setdiff
.
Dany
a <- sample(1:10)
remove <- c(2, 3, 5)
Następnie
> a
[1] 10 8 9 1 3 4 6 7 2 5
> setdiff(a, remove)
[1] 10 8 9 1 4 6 7
a
jest wynikiem innej funkcji, więc możesz robić rzeczy w jednej linii zamiast 3 i zmiennej tymczasowej
%in%
rozwiązanie, jeśli wektor wejściowy zawiera duplikaty (w takim przypadku setdiff
zwróci tylko unikalny zestaw , tj. Bez duplikatów)
fsetdiff
of data.table
package ma all
flagę (domyślnie F), która pozwala zachować duplikaty w wektorze wejściowym.
Możesz to zrobić w następujący sposób:
> 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
Wkrótce
> x = x[ - which(x %in% y)]
which
. Zasadniczo jest to to samo, co odpowiedź @cbeleites.
which
zwraca indeksy wartości PRAWDA. Tak więc znak minus może być użyty do określenia „indeksów innych niż te indeksy”. which
Jest też bardziej czytelny, ponieważ jest bliżej języka naturalnego.
zamiast
x <- x[! x %in% c(2,3,5)]
korzystając z pakietów purrr
i magrittr
możesz:
your_vector %<>% discard(~ .x %in% c(2,3,5))
pozwala to na subset
jednorazowe użycie nazwy wektora. I możesz go używać w rurach :)
Najpierw możemy zdefiniować nowy operator,
"%ni%" = Negate( "%in%" )
Wtedy to jak x nie jest usuwane
x <- 1:10
remove <- c(2,3,5)
x <- x[ x %ni% remove ]
lub dlaczego zdecydować się na usunięcie, przejdź bezpośrednio
x <- x[ x %ni% c(2,3,5)]
AKTUALIZACJA:
Wszystkie powyższe odpowiedzi nie będą działać dla powtarzających się wartości, odpowiedź @ BenBolker za pomocą duplicated()
predykatu rozwiązuje ten problem:
full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]
Oryginalna odpowiedź: tutaj napiszę małą funkcję:
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)
}
więc powiedzmy full_vector=c(1,2,3,4,1)
i searched_vector=c(1,2,3)
.
exclude_val(full_vector,searched_vector)
zwróci (4,1), jednak powyższe odpowiedzi zwrócą tylko (4)
.
full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]
?
full_vector = c(1,1,1,2,3); searched_vector = c(1,1,3);
- to produkuje1, 1, 2
zamiast poprawnej odpowiedzi 1, 2
.
removeif <- function(from, where) { for (i in where) if (i %in% from) {from = from[-match(i, from)]}; from}
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
To ustawia 13 w wektorze na nie liczbę (NAN), pokazuje fałszywe usuwanie (q [c (11,12,13)]). Jeśli spróbujesz tego, zobaczysz, że funkcja usuwania nie działa na numerze wektora. usuwasz cały wektor, ale może nie pojedynczy element.
Jest też subset
coś, co czasami może się przydać:
a <- sample(1:10)
bad <- c(2, 3, 5)
> subset(a, !(a %in% bad))
[1] 9 7 10 6 8 1 4
setdiff
jest lepsze, ponieważ robi wszystko w jednej operacji i odwołuje się do zmienionego wektora tylko raz.