生成与列排列一样多的数据帧
Generate as many data frames as permutation of columns
假设一列保持未排列(在所有生成的数据帧中保持相同的索引位置),我想生成与我的列排列数一样多的数据帧。这是主要数据框:
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
假设第 3 列 (Gamma) 必须保持其位置,对于有限数量的排列,很容易使用列索引并像这样手动排列它们:
data2 <- data1[c(1,4,3,2)]
data2
Alpha Delta Gamma Beta
1 1 22 4 2
2 2 3 8 2
依此类推,直到达到 4 列中的 3 列的所有排列:
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...
它效率低下,而且是大型数据集的噩梦。如何在不手动输入所有排列的情况下快速生成所有数据帧?我认为 permn
或 combn
很有用,但我不能再进一步了。
如果您想要第 3 列仍然是第 3 列的所有排列,那么您可以按如下方式进行
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
更新
如果您希望对象位于名为 data2
, ...., data6
的全局环境中,则调用
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"
假设一列保持未排列(在所有生成的数据帧中保持相同的索引位置),我想生成与我的列排列数一样多的数据帧。这是主要数据框:
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
假设第 3 列 (Gamma) 必须保持其位置,对于有限数量的排列,很容易使用列索引并像这样手动排列它们:
data2 <- data1[c(1,4,3,2)]
data2
Alpha Delta Gamma Beta
1 1 22 4 2
2 2 3 8 2
依此类推,直到达到 4 列中的 3 列的所有排列:
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...
它效率低下,而且是大型数据集的噩梦。如何在不手动输入所有排列的情况下快速生成所有数据帧?我认为 permn
或 combn
很有用,但我不能再进一步了。
如果您想要第 3 列仍然是第 3 列的所有排列,那么您可以按如下方式进行
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
更新
如果您希望对象位于名为 data2
, ...., data6
的全局环境中,则调用
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"