user9798936
user9798936

Reputation:

How to set if condition for a row of matrix inside for lapply function in R

I have a data set where I need to calculate Kendall's tau pair-wisely (between each pair of variables). I want to store the result in a matrix. However, I would like to find the result and if each value at a current row is less than a specific value, then I would like the loop to stop and do not calculate the next correlation (next row), and return 0 values for all entries for all the next rows. I want to do that with lapply function (if possible). In other words, I would like to set a function that works for each row. Then, apply my condition. That is, I can build a function that works for each row separately, then, if the previous row met the condition, all the values in the next rows set to zero.

For example,

Suppose I have the following matrix:

structure(c(5, 4, 3, 1, 2, 0, 4, 3, 2, 1, 0, 0, 3, 2, 1, 0, 0, 
0, 2, 1, 0, 0, 0, 0, 1), .Dim = c(5L, 5L))

Matrix1
     [,1] [,2] [,3] [,4] [,5]
[1,]    5    0    0    0    0
[2,]    4    4    0    0    0
[3,]    3    3    3    0    0
[4,]    1    2    2    2    0
[5,]    2    1    1    1    1

Suppose I would like to find the square root of each entry of the matrix row by row. Then, if all entries of each row are >= 1.6 then, the entries of this row and all comping rows are set to zero, and the for loop stop, return me the matrix as follows:

Matrix1
         [,1] [,2]    [,3]    [,4]   [,5]
    [1,]    0    0       0      0      0
    [2,]    0    0       0      0      0
    [3,]    0    0       0      0      0
    [4,]    1    1.4     1.4    1.4    0
    [5,]    1.4  1       1      1      1


Any help, please?

Upvotes: 2

Views: 213

Answers (1)

akrun
akrun

Reputation: 887851

Here is one with nested for loop.

  1. Initialize the object to be stored ('r.tau') as a matrix with dim attributes from the number of cols (ncol) of the dataset
  2. Do a nested loop on the sequence of columns
  3. If the indexes are not equal, calculate the cor of the columns subset inside the inner loop
  4. Outside the inner loop, add a condition to check whether all the values in that particular row (excluding the 0) are less than or equal to 0.2
  5. If condition from 4 is TRUE, set the row to 0 and break out of the loop
r.tau <- matrix(0, ncol(data), ncol(data))
i1 <- seq_len(ncol(data))
for(i in i1) {    
    for(j in i1) {
        if(i != j) {
          r.tau[i, j] <- cor(data[, i], data[, j])
          }
       
       }
       # // just adding print statements for debugging
       print(r.tau[i, ])
       print(all(setdiff(r.tau[i, ], 0) <= 0.2, na.rm = TRUE))
       
      if(all(setdiff(r.tau[i, ], 0) <= 0.2, na.rm = TRUE)) {
        r.tau[i, ] <- 0
        break
        }
    }

Updated

For the updated condition, we need only a single loop and it can be done from reverse sequence

i1 <- rev(seq_len(ncol(Matrix1)))
for(i in i1) {       
        
          Matrix1[i, ] <- sqrt(Matrix1[i, ])
          if(all(setdiff(Matrix1[i, ], 0) >= 1.6)) {
           Matrix1[i:1, ] <- 0
           break
           
          }
           
          
       
       }

-output

Matrix1
         [,1]     [,2]     [,3]     [,4] [,5]
[1,] 0.000000 0.000000 0.000000 0.000000    0
[2,] 0.000000 0.000000 0.000000 0.000000    0
[3,] 0.000000 0.000000 0.000000 0.000000    0
[4,] 1.000000 1.414214 1.414214 1.414214    0
[5,] 1.414214 1.000000 1.000000 1.000000    1

Or if we need a double loop (for other purpose)

i1 <- rev(seq_len(ncol(Matrix1)))
for(i in i1) { 
   for(j in i1) {            
        
       Matrix1[i, j] <- sqrt(Matrix1[i, j])
          }
          if(all(setdiff(Matrix1[i, j], 0) >= 1.6)) {
           Matrix1[i:1, ] <- 0
           break
          }
          
       
       }

Upvotes: 1

Related Questions