jjulip
jjulip

Reputation: 1133

Add a unique id for each matching pair of values between two columns in R

I would like to add a unique id to each unique pair of values in columns n1 and n2 within the simple example below:

Example data:

>dput(df)
structure(list(n1 = c(5L, 7L, 3L, 9L, 2L, 2L, 4L), y1 = c(1L, 
1L, 2L, 1L, 1L, 1L, 3L), n2 = c(7L, 5L, 4L, 2L, 4L, 4L, 2L), 
    y2 = c(1L, 3L, 1L, 2L, 2L, 3L, 2L)), .Names = c("n1", "y1", 
"n2", "y2"), class = "data.frame", row.names = c(NA, -7L))

>head(df)
  n1 y1 n2 y2 
1  5  1  7  1        
2  7  1  5  3
3  3  2  4  1
4  9  1  2  2
5  2  1  4  2
6  2  1  4  3

Using the below code, I can add a unique pair id based on the combination of values in column n1 relative to column n2, but this does not account for cases where the two values in n1 and n2 have the same combination but are reversed in order in the two columns. For instance in the example below, the pair combination is the same in the final three rows, but because the order of the values is flipped in the final row, the function assumes that they are a different pair combination).

> dfn = transform(df, pairid = as.numeric(interaction(n1, n2, drop=TRUE)))

> dfn
  n1 y1 n2 y2 pairid
1  5  1  7  1      6
2  7  1  5  3      5
3  3  2  4  1      4
4  9  1  2  2      2
5  2  1  4  2      3
6  2  1  4  3      3
7  4  3  2  2      1

My desired output is below.

  n1 y1 n2 y2 pairid
1  5  1  7  1      4
2  7  1  5  3      4
3  3  2  4  1      3
4  9  1  2  2      2
5  2  1  4  2      1
6  2  1  4  3      1
7  4  3  2  2      1

Upvotes: 3

Views: 1768

Answers (1)

kasterma
kasterma

Reputation: 4469

First compute the lesser of the two values, call it m1. Then the larger of the two, call it m2. Then apply your nice interaction trick:

df$pairid <- with(df, {m1 = ifelse(n1 < n2, n1, n2);
                       m2 = ifelse(n1 < n2, n2, n1);
                       return(as.numeric(interaction(m1, m2, drop=TRUE)))})

gives

> df
  n1 y1 n2 y2 pairid
1  5  1  7  1      3
2  7  1  5  3      3
3  3  2  4  1      2
4  9  1  2  2      4
5  2  1  4  2      1
6  2  1  4  3      1
7  4  3  2  2      1

Upvotes: 3

Related Questions