Reputation:
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
Reputation: 887851
Here is one with nested for
loop.
matrix
with dim
attributes from the number of cols (ncol
) of the datasetcor
of the columns subset inside the inner loopall
the values in that particular row (excluding the 0) are less than or equal to 0.2break
out of the loopr.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
}
}
For the updated condition, we need only a single loop and it can be done from rev
erse 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