# Setdiff within mutate function

I have a data frame with three columns. Each row contains three unique numbers between 1 and 5 (inclusive).

df <- data.frame(a=c(1,4,2),
b=c(5,3,1),
c=c(3,1,5))


I want to use mutate to create two additional columns that, for each row, contain the two numbers between 1 and 5 that do not appear in the initial three columns in ascending order. The desired data frame in the example would be:

df2 <- data.frame(a=c(1,4,2),
b=c(5,3,1),
c=c(3,1,5),
d=c(2,2,3),
e=c(4,5,4))


I tried to use the below mutate function utilizing setdiff to accomplish this, but returned NAs rather than the values I was looking for:

df <- df %>% mutate(d=setdiff(c(a,b,c),c(1:5))[1],
e=setdiff(c(a,b,c),c(1:5))[2])


I can get around this by looping through each row (or using an apply function) but would prefer a mutate approach if possible.

Stack Overflow Asked by dm89 on November 15, 2021

Base R:

cbind(df, t(apply(df, 1, setdiff, x = 1:5)))
#   a b c 1 2
# 1 1 5 3 2 4
# 2 4 3 1 2 5
# 3 2 1 5 3 4


Warning: if there are any non-numerical columns, apply will happily up-convert things (converting to a matrix internally).

Answered by r2evans on November 15, 2021

We can use pmap to loop over the rows, create a list column and then unnest it to create two new columns

library(dplyr)
librayr(purrr)
library(tidyr)
df %>%
mutate(out = pmap(., ~ setdiff(1:5, c(...)) %>%
as.list%>%
set_names(c('d', 'e')))) %%>%
unnest_wider(c(out))
# A tibble: 3 x 5
#      a     b     c     d     e
#  <dbl> <dbl> <dbl> <int> <int>
#1     1     5     3     2     4
#2     4     3     1     2     5
#3     2     1     5     3     4


Or using base R

df[c('d', 'e')] <-  do.call(rbind, lapply(asplit(df, 1), function(x) setdiff(1:5, x)))


Answered by akrun on November 15, 2021

## Related Questions

### Why does the new version of ffmpeg play non-interleaved http files so stuck?

0  Asked on August 1, 2020 by fredirty2017

### Succinctly calculate differences between all datetime columns in a row

0  Asked on August 1, 2020 by visionary_20

### How to cut a string to the first “/” from right to left c# .net

1  Asked on August 1, 2020 by ignacio-gomez

### Inserting random data from a list

2  Asked on August 1, 2020 by smiley

### How to exit Java stream processing after a required number of results?

1  Asked on July 31, 2020 by mandroid

### Invalid token SELECT

2  Asked on July 31, 2020 by virendra-varma

### Failing the mock method return with arguments as Parameter

2  Asked on July 30, 2020 by podoi17

### Django – No column found for custom field?

0  Asked on July 29, 2020 by jare42

### Package.json with multiple entrypoints

1  Asked on July 29, 2020 by jeanluca-scaljeri

### REACT vs REACT_PROJECT vs WEBPACK for storybook type?

1  Asked on July 29, 2020 by temporary_user_name

### Random Background Image from Button Click

1  Asked on July 29, 2020 by charmy

### Systemd-journald disk wear-out

0  Asked on July 29, 2020 by rohit

### How to create a new python dictionary from loop results without overwrite

1  Asked on July 29, 2020 by anderson-soares

### Are .NET Standard Messages effectively incompatible with .NET Framework BrokeredMessages for general-purpose message sending?

0  Asked on July 28, 2020 by panzercrisis

### Function composition using Go syntax

1  Asked on July 28, 2020 by overexchange

### How to call two async functions one after the other?

2  Asked on July 28, 2020 by vineet-sharma

### R wordcloud error, invalid cex, unsure of reason

0  Asked on July 27, 2020 by mia-p

### Only left with the last key/value pairs added to a dictionary when I go through a loop in Python

4  Asked on July 26, 2020 by twelsh37

### How does implicit conversion work in Java?

4  Asked on July 25, 2020 by mohsin-ahmed