2017-03-12 12 views
2

私は、定義済みのn値に依存するバイナリ行列の各行に対してビット反転を実行する関数を書いています。 nの値は、マトリックスの各ローに対して1ビットの数を決定します。if else else for aループ

set.seed(123) 
## generate a random 5 by 10 binary matrix 
init <- t(replicate(5, {i <- sample(3:6, 1); sample(c(rep(1, i), rep(0, 10 - i)))})) 
n <- 3 
## init_1 is a used to explain my problem (single row matrix) 
init_1 <- t(replicate(1, {i <- sample(3:6, 1); sample(c(rep(1, i), rep(0, 10 - i)))})) 

bit_inversion関数は、このいくつかのことを行います

  1. 選択された行がnより小さい1'sの数を有する場合、それはランダム数インデックス(difference)を選択し、それらを反転します。
  2. エルス(1から0)選択された行がnより1's大きい数を有する場合、それは、ランダム数のインデックス(difference)を選択し、それらを反転。 (0から1)エルス
  3. は(行がある場合1'sの数はnに等しい。)何もしない以下

は私が実現される機能である:

bit_inversion<- function(pop){ 

     for(i in 1:nrow(pop)){ 
       difference <- abs(sum(pop[i,]) - n) 
       ## checking condition where there are more bits being turned on than n 
       if(sum(pop[i,]) > n){ 
         ## determine position of 1's 
         bit_position_1 <- sample(which(pop[i,]==1), difference) 
         ## bit inversion 
         for(j in 1:length(bit_position_1)){ 
           pop[bit_position_1[j]] <- abs(pop[i,][bit_position_1[j]] - 1) 

         } 
       } 

       else if (sum(pop[i,]) < n){ 
         ## determine position of 0's 
         bit_position_0 <- sample(which(pop[i,]==0), difference) 
         ## bit inversion 
         for(j in 1:length(bit_position_0)){ 
           pop[bit_position_0[j]] <- abs(pop[bit_position_0[j]] - 1) 

         } 
       } 
     } 

     return(pop) 
} 

結果:

call <- bit_inversion(init) 
> rowSums(call) ## suppose to be all 3 
[1] 3 4 5 4 3 

しかし、init_1(単一行行列)を使用すると、funcそれはうまくいくようです。

結果:

call_1 <- bit_inversion(init_1) 
> rowSums(call) 
[1] 3 

は私forif...elseループで間違いはありますか?

+1

0/1行列を生成するための恐ろしいコードです。これを試してください: 'nr < - 5; nc <-10; init < - マトリックス(rbinom(nr * nc、1、0.5)、nrow = nr、ncol = nc) ' –

答えて

2

変更するには、行のインデックスを忘れてしまった

pop[i,bit_position_1[j]] <- abs(pop[i,][bit_position_1[j]] - 1) 

にループ

pop[bit_position_1[j]] <- abs(pop[i,][bit_position_1[j]] - 1) 

のための 'J' の行。

そして、ここにあなたのループのためのよりコンパクトなバージョンです:

for(i in 1:nrow(pop)){ 
    difference <- abs(sum(pop[i,]) - n) 
    logi <- sum(pop[i,]) > n 
    pop[i,sample(which(pop[i,]==logi), difference)] <- !logi 
} 
+0

素晴らしい、ありがとう! –