Как найти элементы одного вектора, которых нет в другом (не используя setdiff) - PullRequest
2 голосов
/ 15 апреля 2019

У меня есть два вектора,

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

y <- c(1,2,3)

И я хочу получить еще один вектор элементов в x, которых нет в y; так что в этом случае (2,4).

Я пытался использовать функцию setdiff (), но она не учитывает дубликаты (она возвращает только 4), поэтому я не уверен, как это сделать.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 15 апреля 2019

Может быть попробовать это:

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

nomatch = 0 необходимо, чтобы избежать смешивания NA с отрицательными индексами.

Для работы с дополнительными дубликатами, как упомянуто в комментариях, другим вариантом может быть использование vsetdiff из пакета vecsets :

library(vecsets)
x = c(1, 2, 2, 3, 3, 4)
y = c(1, 2, 2, 3)
> vsetdiff(x,y)
[1] 3 4
0 голосов
/ 16 апреля 2019

Рассматривая оригинальный пример 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

Создано в 2019-04-15 при представлении пакета (v0.2.1)

0 голосов
/ 15 апреля 2019

Это не даст результаты, как обсуждалось @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...