I design tools that promote animal health and welfare in the zoo and agricultural industries.

I constantly find myself needing a function to subtract two sets from each other, yet can’t find a good way to do this in R.

As a reprex, let’s say `a`

is my inventory of items, and `b`

is a customer order. I want to know what products are left in my warehouse after fulfilling the customer’s order.

For example:

```
a <- c(1,1,1,1,2,2,3,3)
b <- c(1,1,1,3)
```

my remaining inventory is `c(1,2,2,3)`

.

These don’t work:

`setdiff(a,b)`

returns 2`a - b`

iterates subtraction over the vectors`intersect(a,b)`

returns only (1,3) because duplicates are removed`(a[a %in% intersect(a, b)])`

returns too many items`c(1, 1, 1, 1, 3, 3)`

because R includes any matching digit as many times as it matches.

How can I simply remove all elements in one vector from another, treating each item as unique, so not removing duplicates?

Here’s a function I wrote to do that:

```
library(dplyr)
library(tidyr)
```

```
subtract_sets <- function(inventory, order){
inv <- inventory %>%
table() %>%
as_tibble() %>%
rename(item = 1)
ord <- order %>%
as.character() %>%
table() %>%
as_tibble() %>%
rename(item = 1)
final <- left_join(inv, ord, by = "item") %>%
mutate(n.y = replace_na(n.y, 0)) %>%
mutate(Freq = ifelse(n.y >= n.x, 0, n.x - n.y))
as.vector(rep.int(final$item, times = final$Freq))
}
```

Here is the result of that.

```
a <- c(1,1,1,1,2,2,3,3)
b <- c(1,1,1,3)
subtract_sets(a, b)
```

`## [1] "1" "2" "2" "3"`

It works even if the second set has items not in the first set.

```
c <- c(1,1,1,1,2,2,3,3)
d <- c(1,1,1,3,3,3,3,4)
subtract_sets(c, d)
```

`## [1] "1" "2" "2"`