11

This looks easy enough, but I keep bumping my head.

I have the numeric vector v1

v1 <- c(1,1,3,5,7,7) 

And I have a numeric vector v2. v2 is always a subset of v1.
I want to remove the all elements from v2 from v1, but only one (and exaclty one) v1 element per v2 element.

desired output

if v2 <- c(3,5) I want to keep c(1,1,7,7) from v1. This one is easy using v1[-match(v2, v1)].
if v2 <- c(1,7) I want to keep c(1,3,5,7) from v1. also, v1[-match(v2, v1)] does the trick.
if v2 <- c(1,1) I want to keep c(3,5,7,7) from v1. Now v1[-match(v2, v1)] returns [1] 1 3 5 7 7.. Not what I want.

0

4 Answers 4

9

You can use vsetdiff from the "vecsets" library (this will keep the duplicates as opposed to setdiff), in the following way:

library(vecsets) v1 <- c(1,1,3,5,7,7) v2.1 <- c(3,5) > vsetdiff(v1, v2.1) [1] 1 1 7 7 v2.2 <- c(1,7) > vsetdiff(v1, v2.2) [1] 1 3 5 7 v2.3 <- c(1,1) > vsetdiff(v1, v2.3) [1] 3 5 7 7 
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for pointing to the vecsets package.. I can use those functions more often.
@Wimpel sure, its a useful package!
@DavidS Your setdiff approach seems not working giving v2 <- c(1,3,7)
@ThomasIsCoding You are right, I didn't test it for more adge cases, it's strange as even v2<-c(1,3) doesnt work well. probably a bug.
You can keep the vsetdiff solution only, since I don't think setdiff can give a proper way to address this question. You can try Map("*",1:5,c(-1,1)) to see how Map works. The case in your setdiff solution is just a very special case and works coincidently.
5
Reduce(function(x, y) x[-match(y, x)], v2, init = v1) 

Comments

4

There's probably a better way using a truly recursive function, but I think you could accomplish this with a for loop:

v1 <- c(1, 1, 3, 5, 7, 7) v2 <- c(1,1) v1_keep <- v1 for (i in seq_along(v2)){ v1_keep <- v1_keep[-match(v2[i], v1_keep)] } v1_keep # [1] 3 5 7 7 

1 Comment

I try to stay away from for-loops since production data is much larger than the samples given here. but still +1 for giving an answer that is providing the desired output.
2

Using map2

library(purrr) map2(v1, v2, setdiff) %>% flatten 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.