Удалить первое вхождение числа из списка

У меня есть вектор в R со списком символов, включая некоторые, которые являются дубликатами, например.

v<-c("d09","d11","d13","d01","d02","d10","d13")

И еще один вектор, который включает в себя одиночные подсчеты этих символов, например

x<-c("d10","d11","d13")

Я хочу удалить символы из второго вектора, начиная с первого вектора, но сохранить дубликаты. В приведенном выше примере я хотел бы получить

"d09", "d01", "d02", "d13"

Я пробовал разные вещи, например. z<-v[!(v %in% x)], но он сохраняет удаление всех экземпляров символов в x, а не только один из них, поэтому в итоге я получаю следующее:

"d09", "d01", "d02"

Что я могу сделать, чтобы удалить только один экземпляр дублированного элемента?

Ответ 1

Вы можете использовать match и отрицательную индексацию.

v[-match(x, v)]

производит

[1] "d09" "d01" "d02" "d13"

match возвращает только местоположение первого совпадения значения, которое мы используем в наших интересах здесь.

Обратите внимание, что %in% и is.element являются вырожденными версиями match. Для сравнения:

match(x, v)            # [1] 6 2 3
match(x, v) > 0        # [1] TRUE TRUE TRUE
x %in% v               # [1] TRUE TRUE TRUE
is.element(x, v)       # [1] TRUE TRUE TRUE

Последние три являются одинаковыми и в основном связаны с логической версией первого (фактически, см. код для %in% и is.element). При этом вы теряете ключевую информацию, которая представляет собой местоположение первого совпадения x в v и остается только зная, что значения x существуют в v.

Обратное, v %in% x означает что-то отличное от того, что вы хотите, что "значения в v находятся в x", что не будет соответствовать вашему требованию, поскольку все повторяющиеся значения удовлетворяют этому условию.

Ответ 2

is.element

v[!is.element(v,x)]