首页 > 解决方案 > R中两个大矩阵的高效同时置换

问题描述

我有两个对象,都是矩阵:

pop1[,1:5]
>            8:31:+    8:91:+     8:106:+      8:133:+        8:137:+
> [1,]        42        39          36           41              39
> [2,]        26        24          19           25              23
> [3,]        24        25          22           26              22
> [4,]         4         4           2            4               4
> [5,]        34        24          33           33              33
> [6,]        14        14          10           14              12

pop2[,1:5]
>            8:31:+    8:91:+     8:106:+      8:133:+        8:137:+
> [1,]        45        36          36           41              35
> [2,]        26        14          19           25              23
> [3,]        14        25          21           23              20
> [4,]         4         4           2            2               6
> [5,]        29        29          30           31              32
> [6,]        14        17           9           16              10

我想排列每一列。很简单,例如对于 pop1:

pop1.permuted <- do.call('cbind', lapply(as.data.frame(pop1[,1:5]), sample))

问题是我需要以相同的方式洗牌两个矩阵的每一列。例如(组成值):

pop1[,1:2]
>            8:31:+    8:91:+     
> [1,]         1         7         
> [2,]         2         8          
> [3,]         3         9          
> [4,]         4        10           
> [5,]         5        11          
> [6,]         6        12          

pop2[,1:2]
>            8:31:+    8:91:+     
> [1,]         1         7         
> [2,]         2         8          
> [3,]         3         9          
> [4,]         4        10           
> [5,]         5        11          
> [6,]         6        12 

排列后应该是这样的:

pop1[,1:2]
>            8:31:+    8:91:+     
> [1,]         1        11         
> [2,]         5        12          
> [3,]         6         8          
> [4,]         2         9
> [5,]         3        10        
> [6,]         4         7          

pop2[,1:2]      
>            8:31:+    8:91:+     
> [1,]         1        11         
> [2,]         5        12          
> [3,]         6         8          
> [4,]         2         9
> [5,]         3        10        
> [6,]         4         7    

我可以循环遍历列,但有 106,770 列,因此循环遍历所有列 999 次(我想洗牌两个矩阵的次数)需要几天或几周的时间。

到目前为止,我想出的是:

pop1.per <- pop1
pop2.per <- pop2

psi.p=list()
for (i in 1:999){ 
  order <- sample(1:6)
  pop1.per <- do.call('cbind',lapply(pop1.per, 
                                              function(x){x=x[order]
                                                          return(x)}))
  pop2.per <- do.call('cbind',lapply(pop2.per, 
                                              function(x){x=x[order]
                                                          return(x)}))
  psi.p[[i]] <- get.all.psi(pop1.per, pop2.per)         # the calculation I make with the matrices (doesn't really matter)
}

问题是,使用此代码,每列都根据“订单”对象重新排列,但我想要每列的新订单。

所以,我被困在这里,希望能得到一些意见。谢谢你。

更新:

我认为当我每次使用相同的种子时它应该可以工作并且它以这种方式运行得非常快:

pop1.per <- pop1
pop2.per <- pop2
col.sample <- function(x, s){s=s+1; set.seed(s); sample(x)}

psi.p=list()
for (i in 1:999){
  seed <- sample(seq(1000,9999,4),1)
  pop1.per <- sapply(1:ncol(pop1.per), function(cl) col.sample(x= pop1.per[,cl], s=round(seed*cl)))
  pop2.per <- sapply(1:ncol(pop2.per), function(cl) col.sample(x= pop2.per[,cl], s=round(seed*cl)))

  psi.p[[i]] <- get.all.psi(pop1.per, pop2.per)         # the calculation I make with the matrices (doesn't really matter)
}

Julian_Hn 的答案似乎也有效,但我没有尝试(无论如何感谢您的回答)。

标签: rpermutation

解决方案


您可以预先生成排列,然后将它们分别应用于矩阵:

m1 <- matrix(1:50,ncol=5)

m2 <- m1 + 1000

permutations <- replicate(ncol(m1),sample(nrow(m1)))


m1.perm <- sapply(seq_len(ncol(permutations)),function(i) m1[permutations[,i],i])
m2.perm <- sapply(seq_len(ncol(permutations)),function(i) m2[permutations[,i],i])

m1.perm
      [,1] [,2] [,3] [,4] [,5]
 [1,]    9   12   24   32   48
 [2,]    4   14   22   31   47
 [3,]    3   20   23   39   43
 [4,]    7   15   27   37   49
 [5,]    2   17   21   34   46
 [6,]    1   16   30   33   44
 [7,]    5   11   25   40   41
 [8,]   10   13   28   36   45
 [9,]    8   19   29   38   42
[10,]    6   18   26   35   50


m2.perm
      [,1] [,2] [,3] [,4] [,5]
 [1,] 1009 1012 1024 1032 1048
 [2,] 1004 1014 1022 1031 1047
 [3,] 1003 1020 1023 1039 1043
 [4,] 1007 1015 1027 1037 1049
 [5,] 1002 1017 1021 1034 1046
 [6,] 1001 1016 1030 1033 1044
 [7,] 1005 1011 1025 1040 1041
 [8,] 1010 1013 1028 1036 1045
 [9,] 1008 1019 1029 1038 1042
[10,] 1006 1018 1026 1035 1050


推荐阅读