我试图识别那些未包含在另一个向量中的元素。例如,在两个向量中,我有:
list.a <- c("James", "Mary", "Jack", "Sonia", "Michelle", "Vincent")
list.b <- c("James", "Sonia", "Vincent")
有没有一种方法可以验证哪些人不重叠?在这个例子中,我希望获得包含Mary、Jack和Michelle的向量结果。
任何建议都将有所帮助!
有的,有一种方法:
setdiff(list.a, list.b)
# [1] "Mary" "Jack" "Michelle"
我认为需要强调的是,被接受的答案只是部分正确的。命令setdiff(list.a, list.b)
仅在这些元素包含在第一个参数中的对象时才能找到不重叠的元素!如果你不知道这个行为并且使用了setdiff(list.b, list.a)
,结果将在本例中为character(0)
,这会让你得出结论认为没有非重叠元素。
为了举例说明,使用稍微扩展的示例,明显的快速修复方法是:
list.a <- c("James", "Mary", "Jack", "Sonia", "Michelle", "Vincent")
list.b <- c("James", "Sonia", "Vincent", "Iris")
c(setdiff(list.b, list.a), setdiff(list.a, list.b))
# [1] "Iris" "Mary" "Jack" "Michelle"
根据Hadley和我自己的评论,这里是如何允许重复值的扩展回答。
最终编辑:我不建议任何人使用这个方法,因为结果可能与您的预期不符。如果在x中有一个不在y中的重复值,则会看到该值在输出中重复出现。但是:例如,在x中有四个9,在y中有一个9,则所有9都将被删除。人们可能希望保留其中的三个;这需要更加混乱的代码。
mysetdiff<-function (x, y, multiple=FALSE)
{
x <- as.vector(x)
y <- as.vector(y)
if (length(x) || length(y)) {
if (!multiple) {
unique( x[match(x, y, 0L) == 0L])
}else x[match(x, y, 0L) == 0L]
} else x
}
Rgames> x
[1] 8 9 6 10 9
Rgames> y
[1] 5 3 8 8 1
Rgames> setdiff(x,y)
[1] 9 6 10
Rgames> mysetdiff(x,y)
[1] 9 6 10
Rgames> mysetdiff(x,y,mult=T)
[1] 9 6 10 9
Rgames> mysetdiff(y,x,mult=T)
[1] 5 3 1
Rgames> setdiff(y,x)
[1] 5 3 1
if
语句的结果存储到临时变量中,并在 !multiple
的情况下对其调用 unique
,这样代码更易读。 - Matthew Lundberg一个适用于重复项的简洁语句:
anti_join(data_frame(c(1,1,2,2)), data_frame(c(1,1)))
这将返回数据框{2,2}。然而,在1,1,2,2中的1,2情况下不适用,因为它找到了两次。
setdiff
的源代码,您会发现很容易修改它以不忽略重复项。 - hadley