【问题标题】:Finding elements that do not overlap between two vectors查找两个向量之间不重叠的元素
【发布时间】:2014-02-05 10:11:18
【问题描述】:

我正在尝试识别未包含在其他向量中的元素。例如在两个向量中我有

list.a <- c("James", "Mary", "Jack", "Sonia", "Michelle", "Vincent")

list.b <- c("James", "Sonia", "Vincent")

有没有办法验证哪些人没有重叠?在示例中,我想获取包含 Mary、Jack 和 Michelle 的向量结果。

任何建议都会有所帮助!

【问题讨论】:

    标签: r overlap


    【解决方案1】:

    是的,有办法:

    setdiff(list.a, list.b)
    # [1] "Mary"     "Jack"     "Michelle"
    

    【讨论】:

    • 请注意,该组中的所有函数(setdiff、intersect、union 等)都会忽略重复项。如果你有重复值的列表,你将不得不玩一下。事实上,几天前就这个问题有一个 SO 问题,得到了很好的回答。 -- 当然现在我找不到了:-(
    • @CarlWitthoft 如果您查看setdiff 的源代码,您会发现很容易修改为不忽略重复项
    • @hadley 我发布了 setdiff 的“灵活”版本,仅供参考:-)
    【解决方案2】:

    我认为应该提到的是,公认的答案只是部分正确。 命令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" 
    

    【讨论】:

    • 正是发生在我身上的事情。谢谢!
    【解决方案3】:

    基于 Hadley 和我自己的 cmets 的扩展答案:这是允许重复的方法。

    最终编辑:我不建议任何人使用它,因为结果可能不是您所期望的。如果x 中有重复值,而y 中没有,您将在输出中看到该值重复。但是:例如,如果x 中有四个9y 中有一个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。它会更容易阅读。
    【解决方案4】:

    适用于重复的漂亮单行:

    anti_join(data_frame(c(1,1,2,2)), data_frame(c(1,1)))
    

    这将返回数据框 {2,2}。然而,这不适用于 1,1,2,2 中的 1,2 的情况,因为它找到了两次

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多