jacky_learns_to_code - 9 months ago 28

R Question

I am writing a function to perform bit inversion for each row of a binary matrix which depends on a predefined

`n`

`n`

`1`

`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)))}))

The

`bit_inversion`

- If the selected row has number of lesser than
`1's`

, then it randomly select a few indices (`n`

) and invert them. (`difference`

to`0`

)`1`

- Else if the selected row has number of greater than
`1's`

, then it randomly select a few indices (`n`

) and invert them. (`difference`

to`1`

)`0`

- Else do nothing (when the row has number of equals to
`1's`

.)`n`

Below is the function I implemented:

`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)

}

Outcome:

`call <- bit_inversion(init)`

> rowSums(call) ## suppose to be all 3

[1] 3 4 5 4 3

But when using

`init_1`

Outcome:

`call_1 <- bit_inversion(init_1)`

> rowSums(call)

[1] 3

Is there a mistake in my

`for`

`if...else`

Answer Source

Change the line in 'j' for loop

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

into

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

You forgot the row index.

And, here is a more compact version of your for loop:

```
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
}
```