我有一个向量,如下所示:a = c(1:10)
,我需要删除多个值,如:2, 3, 5
如何从向量中删除这些数字(它们并不是向量中的位置)?
目前我循环遍历向量并执行以下操作:
a[!a=NUMBER_TO_REMOVE]
但我认为有一个可以自动完成这个任务的函数。
我有一个向量,如下所示:a = c(1:10)
,我需要删除多个值,如:2, 3, 5
如何从向量中删除这些数字(它们并不是向量中的位置)?
目前我循环遍历向量并执行以下操作:
a[!a=NUMBER_TO_REMOVE]
但我认为有一个可以自动完成这个任务的函数。
%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
中。
If a
can contain incomparables, but remove
will not, we can use match
, telling it to return 0
for non-matches and incomparables (%in%
is a conventient shortcut for 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
is not needed as incomparables will anyways not match, but I'd include it for the sake of readability.
This is, btw., what setdiff
does internally (but without the unique
to throw away duplicates in a
which are not in remove
).
If remove
contains incomparables, you'll have to check for them individually, e.g.
if (any (is.na (remove)))
a <- a [! is.na (a)]
(This does not distinguish NA
from NaN
but the R manual anyways warns that one should not rely on having a difference between them)
For Inf
/ -Inf
you'll have to check both sign
and is.finite
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
a
是另一个函数的结果时,你可以在一行中完成操作,而不需要三个临时变量。 - jf328setdiff
仅返回不带重复值的唯一集合),则与%in%
解决方案产生不同的结果。 - talatdata.table
包的fsetdiff
函数有一个all
标志(默认为F),允许在输入向量中保留重复项。 - Juergenx <- x[! x %in% c(2,3,5)]
purrr
和magrittr
包,您可以进行以下操作:your_vector %<>% discard(~ .x %in% c(2,3,5))
子集
成为可能。而且你可以在管道中使用它 :)您可以按照以下步骤进行:
> 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)]
which
。它基本上与 @cbeleites 的答案相同。 - David Arenburgwhich
返回TRUE值的索引。因此,减号可以用来表示“除这些索引之外的索引”。此外,which
更易读,因为它更接近自然语言。 - ibilgen首先,我们可以定义一个新的运算符,
"%ni%" = Negate( "%in%" )
x <- 1:10
remove <- c(2,3,5)
x <- x[ x %ni% remove ]
x <- x[ x %ni% c(2,3,5)]
有时候也可以使用 subset
:
a <- sample(1:10)
bad <- c(2, 3, 5)
> subset(a, !(a %in% bad))
[1] 9 7 10 6 8 1 4
更新:
以上所有答案都无法处理重复值,@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)
。
full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]
是什么意思? - Ben Bolkerfull_vector = c(1,1,1,2,3); searched_vector = c(1,1,3);
- 会产生 1, 1, 2
而不是正确答案 1, 2
。 - fnlremoveif <- function(from, where) { for (i in where) if (i %in% from) {from = from[-match(i, from)]}; from}
- fnlseq.int.exclude <- function(excluded, ...) {
x <- seq.int(...)
return(x[!(x %in% excluded)])
}
调用示例:
seq.int.exclude(from = 10L, to = 20L, excluded = c(12L, 30L, 19L))
seq.int.exclude(from = 10L, to = 20L, excluded = 15L)
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。 remove(q[c(11,12,13)])。 如果你尝试这样做,你会发现remove函数不能在向量数字上工作。 你可以删除整个向量,但可能不是单个元素。
setdiff
更好,因为它可以在一次操作中完成所有操作,并且仅对修订后的向量进行引用。 - Olexaa
中不在remove
中的重复项。如果这不是问题,您也可以使用setdiff
。顺便说一下,setdiff
使用match
,而%in%
是一个快捷方式。 - cbeleites unhappy with SX