I have a list of matrices. For each matrix within the list I am attempting to denote when a value is < 100 for three consecutive occasions. Ultimately all I need is a 1 for each matrix if the event occurred three times in a row at any point along the sequence, or a 0 if it did not. the code I am providing is higher resolution but I can reduce it down later. Below is the code I have thus far. For some reason it is marking a 1 just at the occurrence of < 100 and not 3 consecutive appearances. I presume the lead function is inappropriate but am stuck at the moment. Am sure a seq_along forloop could be used but am trying to keep it functional. Thanks
set.seed(24)
list_of_matrices <- replicate(100, matrix(rnorm(1*51), nrow = 1), simplify = FALSE)
test<- lapply(list_of_matrices,function(x){ifelse(x & lead(x,1) & lead(x, 2) < 100, 1, NA)})
CodePudding user response:
We may use rle
here
out <- lapply(list_of_matrices, function(m) {
t(apply(m, 1, function(u) {
rl <- rle(u < 100)
rl$values[(rl$lengths < 3) & rl$values] <- FALSE
as.integer(inverse.rle(rl))
}))
})
-output
> out[[1]]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 0 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 1 1 1 1 1 0
[3,] 1 1 1 1 1 0 1 1 1 0
[4,] 0 0 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 0
> list_of_matrices[[1]]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 118 114 88 112 100 116 105 119 112 114
[2,] 98 108 87 116 87 97 85 86 83 100
[3,] 87 89 96 95 97 112 85 80 94 105
[4,] 102 105 87 100 91 116 114 85 82 120
[5,] 113 120 92 91 110 99 112 118 93 80
If it is a list
of vectors, we can directly apply the rle
by looping over the list
lapply(lst1, function(u) {
rl <- rle(u < 100)
rl$values[(rl$lengths < 3) & rl$values] <- FALSE
as.integer(inverse.rle(rl))
})
data
set.seed(24)
list_of_matrices <- replicate(3, matrix(sample(80:120, 5 * 10,
replace = TRUE), ncol = 10, nrow = 5), simplify = FALSE)