0

I would like to generate as many data frames as the number of permutation of my columns, given that one column as to remain unpermutated (keep the same index position in all generated data frames). Here is the main dataframe:

data1 <- data.frame("Alpha"=c(1,2), "Beta"=c(2,2), "Gamma"=c(4,8), "Delta"=c(22,3))
data1
  Alpha Beta Gamma Delta
1     1    2     4    22
2     2    2     8     3

Assume the 3rd colomn (Gamma) must keep its position, for a limited number of permutations, it is easy to use the column index and permute them manually like this:

data2 <- data1[c(1,4,3,2)]
data2

  Alpha Delta Gamma Beta
1     1    22     4    2
2     2     3     8    2

and so on until all permutations of 3 out of 4 columns are reached:

data3 <- data1[c(4,1,3,2)]
data4 <- data1[c(4,2,3,1)]
data5 <- data1[c(2,4,3,1)]
data6 <- data1[c(2,1,3,4)]
data7...

It is inefficient and a nightmare with a large dataset. How to generate all data frames quickly without typing all permutations manually? I think permn or combn are usefull but I am unable to go any further.

Elixterra
  • 281
  • 1
  • 3
  • 11
  • When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Mar 16 '18 at 17:55

1 Answers1

1

If you want all permutations where column 3 is still column 3 then you can do as follows

data1 <- data.frame("Alpha"=c(1,2), "Beta"=c(2,2), "Gamma"=c(4,8), "Delta"=c(22,3))
library(combinat)
idx <- permn(ncol(data1))
idx <- idx[sapply(idx, "[", i = 3) == 3]
res <- lapply(idx, function(x) data1[x])
res 
#R> [[1]]
#R>   Alpha Beta Gamma Delta
#R> 1     1    2     4    22
#R> 2     2    2     8     3
#R> 
#R> [[2]]
#R>   Delta Alpha Gamma Beta
#R> 1    22     1     4    2
#R> 2     3     2     8    2
#R> 
#R> [[3]]
#R>   Alpha Delta Gamma Beta
#R> 1     1    22     4    2
#R> 2     2     3     8    2
#R> 
#R> [[4]]
#R>   Beta Delta Gamma Alpha
#R> 1    2    22     4     1
#R> 2    2     3     8     2
#R> 
#R> [[5]]
#R>   Delta Beta Gamma Alpha
#R> 1    22    2     4     1
#R> 2     3    2     8     2
#R> 
#R> [[6]]
#R>   Beta Alpha Gamma Delta
#R> 1    2     1     4    22
#R> 2    2     2     8     3

Update

If you want the objects to be in the global enviroments called data2, ...., data6 then call

names(res) <- paste0("data", 1:length(res))
list2env(res, .GlobalEnv)
data1
#R>   Alpha Beta Gamma Delta
#R> 1     1    2     4    22
#R> 2     2    2     8     3
data2
#R>   Delta Alpha Gamma Beta
#R> 1    22     1     4    2
#R> 2     3     2     8    2
ls() # all the objects in your global enviroment
#R> [1] "data1" "data2" "data3" "data4" "data5" "data6" "idx"   "res"  
  • If I understand correctly, `idx <- permn(ncol(data1))` generates all permutations and `idx <- idx[sapply(idx, "[", i = 3) == 3]` keeps in `idx` only permutations for which i=3. The `lapply` part returns the list. This last step is not exactly what I am looking for. I need the results as separate data frames `data2`, `data3` and so on so that I can apply a calculus R sheet to each data.frame separately. – Elixterra Mar 18 '18 at 08:17
  • @Elixterra for the first part yes. For the latter part, see my updated answer. – Benjamin Christoffersen Mar 18 '18 at 09:03
  • The update corresponds to what I am looking for. Assume now that I want the generated data frames to somehow keep track of the permutation order in their names. For example by using the first letter of each column name: instead of having `data1`, `data2`, having `dataABGD`, `dataDAGB`. Is it easily doable? Maybe this question requires a new topic. – Elixterra Mar 19 '18 at 08:57