【问题标题】:How to find elements of one vector that aren't in another (not using setdiff)如何查找一个向量中不在另一个向量中的元素(不使用 setdiff)
【发布时间】:2019-09-05 20:50:55
【问题描述】:

我有两个向量,

x <- c(1,2,2,3,4)

y <- c(1,2,3)

我想得到另一个不在 y 中的 x 中元素的向量;所以在这种情况下是 (2,4)。

我尝试过使用 setdiff() 函数,但这并没有考虑到重复项(它只会返回 4 个),所以我不知道该怎么做。

谢谢!

【问题讨论】:

  • y 是否可能有重复项?例如,如果x = c(1, 2, 2, 3, 3, 4)y = c(1, 2, 2, 3),你想要结果3 4吗?
  • 我的意思是,这是一个问题。这就是你想要的吗?

标签: r set-difference


【解决方案1】:

不妨试试这个:

x[-match(y,x,nomatch = 0)]

nomatch = 0 是必要的,以避免将 NA 与负下标混合。

如 cmets 中所述,要处理额外的重复项,另一种选择可能是使用 vecsets 包中的 vsetdiff

library(vecsets)
x = c(1, 2, 2, 3, 3, 4)
y = c(1, 2, 2, 3)
> vsetdiff(x,y)
[1] 3 4

【讨论】:

  • 不确定 OP 的欺骗案例有多复杂,但如果 y 有重复,这只会删除第一个,即使它也在 x 中重复。例如,x = c(1, 2, 2, 3, 3, 4)y = c(1, 2, 2, 3) 给出了2 3 4,但我最好的猜测是 OP 想要3 4
  • OP 的例子也没有 ;)
  • 感谢您的回答和分享包!
【解决方案2】:

它不会给出@Gregor 讨论的结果,但是,它应该根据示例给出正确的结果:

x[duplicated(x) | !x %in% y]

[1] 2 4

在各个步骤中:

duplicated(x)

[1] FALSE FALSE  TRUE FALSE FALSE

!x %in% y

[1] FALSE FALSE FALSE FALSE  TRUE

duplicated(x) | !x %in% y

[1] FALSE FALSE  TRUE FALSE  TRUE

【讨论】:

    【解决方案3】:

    考虑到 OP 的原始示例并阅读 @Gregor 的评论,我编写了以下函数,它可以满足 OP 的要求,同时也考虑了 @Gregor 指出的内容

    ## function to find values in x that are absent in y
    x.not.in.y <- function(x, y) {
      # get freq tables for x and y
      x.tab <- table(x)
      y.tab <- table(y)
      # if a value is missing in y then set its freq to zero
      y.tab[setdiff(names(x.tab), names(y.tab))] = 0
      y.tab <- y.tab[names(y.tab) %in% names(x.tab)]
      # get the difference of x and y freq and keep if > 0
      diff.tab <- x.tab[order(names(x.tab))] - y.tab[order(names(y.tab))]
      diff.tab <- diff.tab[diff.tab > 0]
      # output vector of x values missing in y
      unlist(
        lapply(names(diff.tab), function(val) {
          rep(as.numeric(val), diff.tab[val])
        }), 
        use.names = F)
    }
    
    # OP's original data
    x.not.in.y(x = c(1,2,2,3,4), y = c(1,2,3))
    #> [1] 2 4
    
    # @Gregor's data
    x.not.in.y(x = c(1,2,2,3,3,4), y = c(1,2,2,3))
    #> [1] 3 4
    
    # some other data with extra value in y but absent in y
    x.not.in.y(x = c(1,2,2,2,2,3,3,3,4,5), y = c(1,2,3,6))
    #> [1] 2 2 2 3 3 4 5
    

    reprex package (v0.2.1) 于 2019 年 4 月 15 日创建

    【讨论】:

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