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 NAlub Inf)również (podczas gdy zachowa zduplikowane wartości, ao ile nie są wymienione remove).
Jeśli amoże zawierać nieporównywalne, ale removenie będzie, możemy użyć match, mówiąc mu, aby zwracał 0po 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 = 0nie 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 setdiffrobi wewnętrznie (ale bez uniquewyrzucania duplikatów, w aktórych nie ma remove).
Jeśli removezawiera nieporównywalne elementy, będziesz musiał sprawdzić je indywidualnie, np
if (any (is.na (remove)))
a <- a [! is.na (a)]
(To nie odróżnia NAod NaNale instrukcja R jakikolwiek ostrzega, że nie należy liczyć na o różnicę między nimi)
Dla Inf/ -Infbędziesz musiał sprawdzić zarówno signiis.finite
aktórych również nie ma remove. Jeśli to nie problem, możesz również użyć setdiff. setdiff, przy okazji, używa matchdo 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
ajest 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 setdiffzwróci tylko unikalny zestaw , tj. Bez duplikatów)
fsetdiffof data.tablepackage ma allflagę (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.
whichzwraca indeksy wartości PRAWDA. Tak więc znak minus może być użyty do określenia „indeksów innych niż te indeksy”. whichJest też bardziej czytelny, ponieważ jest bliżej języka naturalnego.
zamiast
x <- x[! x %in% c(2,3,5)]
korzystając z pakietów purrri magrittrmożesz:
your_vector %<>% discard(~ .x %in% c(2,3,5))
pozwala to na subsetjednorazowe 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ż subsetcoś, 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
setdiffjest lepsze, ponieważ robi wszystko w jednej operacji i odwołuje się do zmienionego wektora tylko raz.