我有两个载体
a <- c(1:20)
b <- c(2,11,14)
我想根据b中的向量条目删除向量中的条目(我希望删除第2个,第11个和第14个条目)。
我尝试了几种方法,包括:
c <- a[!a %in% b]
但这不起作用。
有什么建议吗?我尝试过搜索SO,但只能根据值找到删除。
答案 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帖子的基准数据。