carolin
carolin

Reputation: 1

Make combinations in R

I want to make combinations of names from the same column (here, changing names to numbers for easier visual)

Given the following data:

Col1
1
2
3
4
5
6

How do I generate the following:

Col1   Col2
1      2
1      3
2      3
1      4
2      4
3      4
1      5
2      5
3      5
4      5
1      6
2      6
3      6
4      6
5      6

test <- combn(data$`row ID`,2)
test <- t(test)

I get:

1   2
1   3
1   4
1   5
1   6
2   3
2   4
2   5
2   6
3   4
3   5
3   6
4   5
4   6
5   6

Thank you in advance!

Upvotes: 0

Views: 84

Answers (4)

jay.sf
jay.sf

Reputation: 73622

Essentially what you want is to cbind growing sequences based on x-value of Col1 with x + 1 repeated x times. You could write a function f that does exactly this,

f <- function(x) cbind(seq(x), rep(x + 1, x))

Mapply it on Col1, and rbind the result.

do.call(rbind, Map(f, d$Col1[-length(d$Col1)]))
#       [,1] [,2]
#  [1,]    1    2
#  [2,]    1    3
#  [3,]    2    3
#  [4,]    1    4
#  [5,]    2    4
#  [6,]    3    4
#  [7,]    1    5
#  [8,]    2    5
#  [9,]    3    5
# [10,]    4    5
# [11,]    1    6
# [12,]    2    6
# [13,]    3    6
# [14,]    4    6
# [15,]    5    6  

Data

d <- data.frame(Col1=1:6)

Upvotes: 0

Shree
Shree

Reputation: 11150

Here's a way in base R using expand.grid and subset -

# domains of values for col1 and col2 are certainly known beforehand
# so can be directly input/generated to be used in expand.grid()
subset(expand.grid(col1 = 1:5, col2 = 2:6), col1 < col2)

   col1 col2
1     1    2
6     1    3
7     2    3
11    1    4
12    2    4
13    3    4
16    1    5
17    2    5
18    3    5
19    4    5
21    1    6
22    2    6
23    3    6
24    4    6
25    5    6

Another approach using lapply -

col1 = 1:5
col2 = 2:6

do.call(
  rbind,
  lapply(col1, function(x) cbind(col1 = x, col2 = col2[x < col2]))
)

      col1 col2
 [1,]    1    2
 [2,]    1    3
 [3,]    1    4
 [4,]    1    5
 [5,]    1    6
 [6,]    2    3
 [7,]    2    4
 [8,]    2    5
 [9,]    2    6
[10,]    3    4
[11,]    3    5
[12,]    3    6
[13,]    4    5
[14,]    4    6
[15,]    5    6

Upvotes: 0

d.b
d.b

Reputation: 32558

i = 1:NROW(d)
data.frame(Col1 = d$Col1[sequence(head(i, -1))],
           Col2 = d$Col1[rep(i[-1], head(i, -1))])
#   Col1 Col2
#1     1    2
#2     1    3
#3     2    3
#4     1    4
#5     2    4
#6     3    4
#7     1    5
#8     2    5
#9     3    5
#10    4    5
#11    1    6
#12    2    6
#13    3    6
#14    4    6
#15    5    6

DATA

d = data.frame(Col1 = 1:6)

Upvotes: 1

Onyambu
Onyambu

Reputation: 79338

Just order your text matrix using the second column

setNames(data.frame(test[order(test[,2]),]),paste0("col",1:2))
   col1 col2
1     1    2
2     1    3
3     2    3
4     1    4
5     2    4
6     3    4
7     1    5
8     2    5
9     3    5
10    4    5
11    1    6
12    2    6
13    3    6
14    4    6
15    5    6

Upvotes: 0

Related Questions