1

Suppose that I have a dataframe

data.frame(v1 = c(1,1,1,2,2,3), v2 = c(6,1,6,3,4,2))
  v1 v2
1  1  6
2  1  1
3  1  6
4  2  3
5  2  4
6  3  2

Is there an R function to return the following dataframe? i.e. the combinations of v2 with based on the unique values of v1

data.frame(v1 = rep(1:3, 6), v2 = c(6,3,2, 6,4,2, 1,3,2, 1,4,2, 6,3,2, 6,4,2))

   v1 v2
1   1  6
2   2  3
3   3  2
4   1  6
5   2  4
6   3  2
7   1  1
8   2  3
9   3  2
10  1  1
11  2  4
12  3  2
13  1  6
14  2  3
15  3  2
16  1  6
17  2  4
18  3  2

P.S. I don't think my question is duplicated. Here v2 has duplicated values and the output dataframe has to keep the order (i.e. v1 = c(1,2,3, 1,2,3, ...). The desired out put has 18 rows but expand.grid gives 36 rows and crossing gives 15 rows

Min
  • 179
  • 9
  • `do.call(expand.grid(your_data))` for all combinations, `expand.grid(v1 = unique(your_data$v1), v2 = your_data$v2)` for your case, if I understand correctly. – Gregor Thomas Feb 03 '21 at 03:43
  • @GregorThomas Thanks Gregor, it's sort of what I want, but the order of v2 doesn't seem to be right. `expand.grid(unique(v1), v2)` gives the following v2: `c(6,6,6,1,1,1,6,6,6,3,3,3,4,4,4,2,2,2)`, which is different from the desired output dataframe... – Min Feb 03 '21 at 03:57
  • What is the logic of output? For `v1` unique values of `v1` are repeated i.e 1, 2 and 3. How is `v2` generated? Is `v2` all combinations of unique values of `v2` ? – Ronak Shah Feb 03 '21 at 03:58
  • @RonakShah Sorry maybe the question isn't very clear. Here `v1` has 3 levels, i.e. 1,2,3 and level one has 3 duplicates, which is shown in `v2`. Let v2(row1) denote the first row of v2, then what I want for the new `v2` is, `c(v2(row1), v2(row4), v2(row6), v2(row1), v2(row5), v2(row6), v2(row2), v2(row4), v2(row6), v2(row2), v2(row5), v2(row6), ...)`, hence 18 rows in total in this order – Min Feb 03 '21 at 04:05
  • @RonakShah Or alternatively, the desired output may also be a list, where the first element is a dataframe with `v2 = (v2(row1), v2(row4), v2(row6))`, the second element is `v2 = (v2(row1), v2(row5), v2(row6))`, the third element is `v2 = (v2(row2), v2(row4), v2(row6))` etc. So there are 6 dataframes in this list – Min Feb 03 '21 at 04:07

1 Answers1

2

Try the code below

dfout <- data.frame(
  v1 = unique(df$v1),
  v2 = c(t(rev(expand.grid(rev(with(df, split(v2, v1)))))))
)

which gives

> dfout
   v1 v2
1   1  6
2   2  3
3   3  2
4   1  6
5   2  4
6   3  2
7   1  1
8   2  3
9   3  2
10  1  1
11  2  4
12  3  2
13  1  6
14  2  3
15  3  2
16  1  6
17  2  4
18  3  2
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81