删除基于另一个向量的向量条目

时间:2016-06-06 00:41:42

标签: r

我有两个载体

a <- c(1:20)
b <- c(2,11,14)

我想根据b中的向量条目删除向量中的条目(我希望删除第2个,第11个和第14个条目)。

我尝试了几种方法,包括:

c <- a[!a %in% b]

但这不起作用。

有什么建议吗?我尝试过搜索SO,但只能根据值找到删除。

2 个答案:

答案 0 :(得分:5)

您只需索引到a并删除b中索引处的元素,如下所示:

a <- c(1:20)
b <- c(2,11,14)
a[-b]
 [1]  1  3  4  5  6  7  8  9 10 12 13 15 16 17 18 19 20

我创建了310万个条目,并随机抽样100,000以删除。可以看出,它的速度非常快。

a <- 1:3100000
b <- sample(a, 100000)
system.time(a[-b])
   user  system elapsed 
  0.024   0.003   0.027 

已编辑:根据akrun和thelatemail下面的评论添加此额外检查选项,以处理b可能为空的情况。

a[if(length(b)) -b else TRUE]

答案 1 :(得分:3)

@Gopala的方法在大多数情况下都有效,除非'b'向量为NULL。为了使其更加通用,我们可以使用seq_along(a) %in%来获得逻辑条件

a[!seq_along(a) %in% b]
#[1]  1  3  4  5  6  7  8  9 10 12 13 15 16 17 18 19 20

现在,如果我们将'b'改为

b <- vector('integer')
a[-b]
#integer(0)
a[!seq_along(a) %in% b]
#[1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

前者返回长度为0的向量,而%in%方法返回整个向量“a”。

其他方法显然更有效,但如果我们需要一种适用于我提到的案例的方法,可以使用它。

system.time(a[-b])
# user  system elapsed 
#  0.07    0.00    0.08 
system.time(a[!seq_along(a) %in% b])
#  user  system elapsed 
#  0.17    0.01    0.18 

@thelatemail发布的方法使第一种方法成为通用

system.time(a[if(length(b)==0) TRUE else -b])
# user  system elapsed 
#  0.05    0.00    0.05 

注意:来自@ Gopala帖子的基准数据。