我有两个向量:
a = c(1,1,2,2,3,3,4,4)
b = c(1)
我想从b
删除a
的第一个匹配。因此,此处仅从1
中删除了第一个a
:
c = c(1,2,2,3,3,4,4)
a
中的项目顺序并不重要。
我试过这段代码:
a[a != b]
a[! a %in% b]
两个结果都是:
[1] 2 2 3 3 4 4.
删除所有1个数字。但是,我只想从b
中删除a
中的特定项目。
如果b = c(1, 1, 2)
,那么我希望结果
[1] 2 3 3 4 4
a[-(1:3)]
上述代码可能会导致[1] 2 3 3 4 4
的结果。但是,我希望它可以更灵活。例如,当项目的顺序未知或随机时:
a = c(3,4,3,1,2,2,1,4)
我怎样才能使用R?
答案 0 :(得分:4)
vecsets
包可以执行标准集操作,同时保留重复项:
vecsets::vsetdiff( c(1,1,2,2,3,3,4,4), c(1) )
## [1] 1 2 2 3 3 4 4
vecsets::vsetdiff( c(1,1,2,2,3,3,4,4), c(1,1,2) )
## [1] 2 3 3 4 4
请注意,它将保留第一个参数的顺序。使用你的上一个例子:
vecsets::vsetdiff( c(3,4,3,1,2,2,1,4), c(1,1,2) )
## [1] 3 4 3 2 4
答案 1 :(得分:3)
从this answer获取灵感,我在评论中链接了一个问题,您可以使用data.table包中的all
。
它需要setdiff
作为参数,这样可以避免只返回唯一值,就像library(data.table)
# with your first example (b = c(1)):
unlist(fsetdiff(data.table(v1=a), data.table(v1=b), all = TRUE))
# v11 v12 v13 v14 v15 v16 v17
# 1 2 2 3 3 4 4
# with second example (b = c(1, 1, 2)):
unlist(fsetdiff(data.table(v1=a), data.table(v1=b), all = TRUE))
# v11 v12 v13 v14 v15
# 2 3 3 4 4
一样:
mail.gimap.usesocketchannels
答案 2 :(得分:2)
您可以使用which()
a = c(3, 4, 3, 1, 2, 2, 1, 4)
a
## [1] 3 4 3 1 2 2 1 4
b = 1
a[- which(a %in% b)[1]]
## [1] 3 4 3 2 2 1 4
案例 b 有两个要素:
b2 = c(1, 2)
sapply(seq_along(b1), function(x) a <<- a[- which(a == x)[1]])[[2]]
## [1] 3 4 3 2 1 4
或者三......
b3 <- c(1, 2, 3)
sapply(seq_along(b1), function(x) a <<- a[- which(a == x)[1]])[[3]]
# [1] 4 3 2 1 4
答案 3 :(得分:0)
我不认为以下是最好的解决方案(vecsets
方法让我觉得最好),但@Aaron关于可能使用Rcpp的评论让我感到有趣。这是我第一次使用该软件包。如果不出意外,我能够在不到20分钟内获得工作代码的事实强调了他的观点,即Rcpp让它相对容易:
library(Rcpp)
cppFunction('
NumericVector difference(NumericVector xs, NumericVector ys){
int m = xs.size();
int n = ys.size();
float flag = 1 + abs(max(xs)) + abs(max(ys)); //occurs in neither xs nor ys
NumericVector zs = clone(xs);
for(int i = 0; i < n; i++){
double y = ys[i];
int j = 0;
while(j < m && zs[j]!= y) j++;
if(j < m) zs[j] = flag;
}
int count = 0;
for(int k = 0; k < m; k++){
if(zs[k] < flag) count++;
}
NumericVector ws(count);
int k = 0;
for(int j = 0; j < m; j++){
if(zs[j] < flag){
ws[k] = zs[j];
k++;
}
}
return ws;
}
')
您的来源:
> a = c(1,1,2,2,3,3,4,4)
> b = c(1,2,1)
> difference(a,b)
[1] 2 3 3 4 4
由于这是我第一次尝试这样的代码,我确信它可以通过多种方式进行改进。
答案 4 :(得分:0)
有点令人沮丧的是语法顺序,但是Reduce
和which
只用Base R来做。
Reduce(b, a) a[-which(a==b)[1]], a, b)