Jonathan1234
Jonathan1234

Reputation: 499

Changing particular cells of a Matrix iteratively in R

Suppose that we have a (4,4) matrix. My goal is to change iteratively that cells (1,1),(2,1),(3,1),(1,2),(2,2),(1,3)

I wrote the following

for(i in 1:3){
 for(j in 1:3){
   if(i>j){
  A[i,j] = A[i,j] + sample(c(-1,1),prob=c(0.5,0.5))
}
}

However, it doesn't change the correct cells and misses cells that have to be changed.

The matrix A can be of the form

A = matrix(c(1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0),4,4,byrow=T)

I think that the following chunk of code might be the solution, at least it gives the correct answer for a few runs that I did.

A = matrix(c(1,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0),4,4,byrow=T)

k = 0 
for(i in 1:3){
  for(j in 1:(3-k)){
    A[i,j] = A[i,j] + sample(c(-1,1),prob=c(0.5,0.5), size = 1)
  }
  k = k + 1
}


Upvotes: 1

Views: 185

Answers (2)

jay.sf
jay.sf

Reputation: 72803

I think you simple forgot to set the size= parameter of sample to get one draw of the Rademacher universe.

set.seed(42)
for (i in 1:3) {
  for (j in 1:3) {
    if (i > j) {
      A[i, j] <- A[i, j] + sample(c(-1, 1), size=1, prob=c(0.5, 0.5))
    }
  }
}
A
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    1    1
# [2,]    0    1    1    0
# [3,]    0    2    0    0
# [4,]    1    0    0    0

Another idea is to use a permutation matrix, which you may subset to your needs, and over which you may loop.

id <- RcppAlgos::permuteGeneral(ncol(B) - 1, ncol(B) - 2, repetition=T)
(id <- id[c(1, 4, 7, 2, 5, 3), ])
#      [,1] [,2]
# [1,]    1    1
# [2,]    2    1
# [3,]    3    1
# [4,]    1    2
# [5,]    2    2
# [6,]    1    3

set.seed(42)
for (i in 1:nrow(id)) {
  A[id[i, 1], id[i, 2]] <- A[id[i, 1], id[i, 2]] + 
    sample(c(-1, 1), size=1, prob=c(0.5, 0.5))
}
A
#      [,1] [,2] [,3] [,4]
# [1,]    0    0    0    1
# [2,]    0    0    1    0
# [3,]    2    1    0    0
# [4,]    1    0    0    0

Upvotes: 2

akrun
akrun

Reputation: 887098

We can create a row/column index (vectorized approach) by cbinding the vector of index. Use the index to subset the cells of the matrix and assign (<-) after adding the sample output to those elements

n <- 3
j1 <- rep(seq_len(n), rev(seq_len(n)))
i1 <- ave(j1, j1, FUN = seq_along)
ind <- cbind(i1, j1)
ind
#     i1 j1
#[1,]  1  1
#[2,]  2  1
#[3,]  3  1
#[4,]  1  2
#[5,]  2  2
#[6,]  1  3


A[ind] <- A[ind] + sample(c(-1,1),prob=c(0.5,0.5), 
         size = nrow(ind), replace= TRUE)

Upvotes: 1

Related Questions