I have the next matrix:
structure(c(0, 0, NA, NA, NA, NA, 0, 0, NA, NA, NA, 1, NA, NA,
NA, NA, 0, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA,
1, 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, 1, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, 0,
1, 1, 0, NA, NA, 0, 1, 1, NA, 1, 0, 0, 0, NA, NA, 0, 1, 1, 0,
0, 1, 0, 0, 0, 0, 1, 1, NA, NA, 0, 1, 1, 0, NA, NA, 1, 1, NA,
NA, 1, 0, 1, 1, NA, NA, 0, 1, 1, 1, 0, 1, 0, NA, NA, NA, NA,
NA, NA, NA, 0, 1, 1, 0, NA, NA, 1, 1, NA, NA, 1, 0, NA, NA, NA,
NA, 0, 1, NA, NA, 0, 1, 0, NA, NA, NA, NA, NA, NA, NA, NA, 1,
1, 0, NA, NA, 1, 1, NA, NA, 1, 0, NA, NA, NA, NA, 0, 1, NA, NA,
1, 1, 0, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, 0, NA, NA, 1,
1, NA, NA, 1, 0, NA, 1, NA, NA, 1, 1, NA, NA, NA, NA, 0, NA,
NA, NA, NA, NA), dim = c(30L, 7L), dimnames = list(c("1", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
"15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25",
"26", "27", "28", "29", "30"), c("1", "2", "4", "5", "6", "7",
"8")))
I need to generate a matrix in the following way:
Let's suppose a row of this matrix:
0,1,1,1,1,1,1
I would like to define:
-1,0,1,2,3,4,5,6
Where zero means the time of the event of interest.
If I have elements with NA I would like to get something like this:
NA,NA,0,1,NA,NA,1
I would like to get:
NA,NA,-1,0,NA,NA,3
with a row like this:
NA,1,1,1,NA,NA,1
NA,0,1,2,NA,NA,5
I hope these specific could clarify my objective:
CodePudding user response:
A vectorized solution using max.col
, sequence
, and matrix indexing:
f <- function(m) {
blnNA <- is.na(m)
m[blnNA] <- 0
i <- max.col(m, "first")
x <- m[matrix(c(1:nrow(m), i), ncol = 2)]
m <- matrix(sequence(rep(ncol(m), nrow(m)), x*(1 - i), x), nrow(m), ncol(m), 1)
m[blnNA] <- NA
m
}
f(m)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] -1 0 NA NA NA NA NA
#> [2,] 0 0 NA NA NA NA NA
#> [3,] NA NA 0 0 0 NA NA
#> [4,] NA NA 0 1 2 3 4
#> [5,] NA NA 0 1 2 3 4
#> [6,] NA NA 0 0 0 0 0
#> [7,] 0 NA NA NA NA NA NA
#> [8,] 0 0 NA NA NA NA NA
#> [9,] NA NA -1 0 1 2 3
#> [10,] NA NA 0 1 2 3 4
#> [11,] NA NA 0 NA NA NA NA
#> [12,] 0 1 NA NA NA NA NA
#> [13,] NA NA 0 1 2 3 4
#> [14,] NA NA 0 0 0 0 0
#> [15,] NA NA -1 0 NA NA NA
#> [16,] NA NA -1 0 NA NA 3
#> [17,] 0 NA NA NA NA NA NA
#> [18,] 0 NA NA NA NA NA NA
#> [19,] NA NA -4 -3 -2 -1 0
#> [20,] NA NA 0 1 2 3 4
#> [21,] NA NA 0 1 NA NA NA
#> [22,] NA NA -1 0 NA NA NA
#> [23,] NA NA -3 -2 -1 0 NA
#> [24,] NA NA 0 1 2 3 NA
#> [25,] NA NA 0 0 0 0 0
#> [26,] NA NA 0 NA NA NA NA
#> [27,] NA NA 0 NA NA NA NA
#> [28,] NA NA 0 NA NA NA NA
#> [29,] 0 1 2 NA NA NA NA
#> [30,] NA 0 1 NA NA NA NA
Edit: to clearly denote rows without a 1
, as suggested by Robert Hacken:
f <- function(m) {
idxNA <- which(is.na(m))
m[idxNA] <- 0
i <- max.col(m, "first")
x <- m[matrix(c(1:nrow(m), i), ncol = 2)]
m <- matrix(sequence(rep(ncol(m), nrow(m)), x*(1 - i) - 1, x), nrow(m), ncol(m), 1)/x 1
m[idxNA] <- NA
m
}
f(m)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] -1 0 NA NA NA NA NA
#> [2,] -Inf -Inf NA NA NA NA NA
#> [3,] NA NA -Inf -Inf -Inf NA NA
#> [4,] NA NA 0 1 2 3 4
#> [5,] NA NA 0 1 2 3 4
#> [6,] NA NA -Inf -Inf -Inf -Inf -Inf
#> [7,] -Inf NA NA NA NA NA NA
#> [8,] -Inf -Inf NA NA NA NA NA
#> [9,] NA NA -1 0 1 2 3
#> [10,] NA NA 0 1 2 3 4
#> [11,] NA NA 0 NA NA NA NA
#> [12,] 0 1 NA NA NA NA NA
#> [13,] NA NA 0 1 2 3 4
#> [14,] NA NA -Inf -Inf -Inf -Inf -Inf
#> [15,] NA NA -1 0 NA NA NA
#> [16,] NA NA -1 0 NA NA 3
#> [17,] -Inf NA NA NA NA NA NA
#> [18,] 0 NA NA NA NA NA NA
#> [19,] NA NA -4 -3 -2 -1 0
#> [20,] NA NA 0 1 2 3 4
#> [21,] NA NA 0 1 NA NA NA
#> [22,] NA NA -1 0 NA NA NA
#> [23,] NA NA -3 -2 -1 0 NA
#> [24,] NA NA 0 1 2 3 NA
#> [25,] NA NA -Inf -Inf -Inf -Inf -Inf
#> [26,] NA NA -Inf NA NA NA NA
#> [27,] NA NA -Inf NA NA NA NA
#> [28,] NA NA -Inf NA NA NA NA
#> [29,] 0 1 2 NA NA NA NA
#> [30,] NA 0 1 NA NA NA NA
CodePudding user response:
You can do this:
mat[] <- t(apply(mat, 1, \(x) (seq_along(x) - min(which(x == 1))) x*0))
#mat[is.infinite(mat)] <- 0
output
> mat
1 2 4 5 6 7 8
1 -1 0 NA NA NA NA NA
2 -Inf -Inf NA NA NA NA NA
3 NA NA -Inf -Inf -Inf NA NA
4 NA NA 0 1 2 3 4
5 NA NA 0 1 2 3 4
6 NA NA -Inf -Inf -Inf -Inf -Inf
7 -Inf NA NA NA NA NA NA
8 -Inf -Inf NA NA NA NA NA
9 NA NA -1 0 1 2 3
10 NA NA 0 1 2 3 4
11 NA NA 0 NA NA NA NA
12 0 1 NA NA NA NA NA
13 NA NA 0 1 2 3 4
14 NA NA -Inf -Inf -Inf -Inf -Inf
15 NA NA -1 0 NA NA NA
16 NA NA -1 0 NA NA 3
17 -Inf NA NA NA NA NA NA
18 0 NA NA NA NA NA NA
19 NA NA -4 -3 -2 -1 0
20 NA NA 0 1 2 3 4
21 NA NA 0 1 NA NA NA
22 NA NA -1 0 NA NA NA
23 NA NA -3 -2 -1 0 NA
24 NA NA 0 1 2 3 NA
25 NA NA -Inf -Inf -Inf -Inf -Inf
26 NA NA -Inf NA NA NA NA
27 NA NA -Inf NA NA NA NA
28 NA NA -Inf NA NA NA NA
29 0 1 2 NA NA NA NA
30 NA 0 1 NA NA NA NA
CodePudding user response:
This could be a solution.
However you must specify what happens when all entries are zero or NA. You therefore must modify nomatch
argument to adapt to your specification.
m <- structure(c(0, 0, NA, NA, NA, NA, 0, 0, NA, NA, NA, 1, NA, NA,
NA, NA, 0, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA,
1, 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, 1, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, 0,
1, 1, 0, NA, NA, 0, 1, 1, NA, 1, 0, 0, 0, NA, NA, 0, 1, 1, 0,
0, 1, 0, 0, 0, 0, 1, 1, NA, NA, 0, 1, 1, 0, NA, NA, 1, 1, NA,
NA, 1, 0, 1, 1, NA, NA, 0, 1, 1, 1, 0, 1, 0, NA, NA, NA, NA,
NA, NA, NA, 0, 1, 1, 0, NA, NA, 1, 1, NA, NA, 1, 0, NA, NA, NA,
NA, 0, 1, NA, NA, 0, 1, 0, NA, NA, NA, NA, NA, NA, NA, NA, 1,
1, 0, NA, NA, 1, 1, NA, NA, 1, 0, NA, NA, NA, NA, 0, 1, NA, NA,
1, 1, 0, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, 0, NA, NA, 1,
1, NA, NA, 1, 0, NA, 1, NA, NA, 1, 1, NA, NA, NA, NA, 0, NA,
NA, NA, NA, NA), dim = c(30L, 7L), dimnames = list(c("1", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
"15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25",
"26", "27", "28", "29", "30"), c("1", "2", "4", "5", "6", "7",
"8")))
m
#> 1 2 4 5 6 7 8
#> 1 0 1 NA NA NA NA NA
#> 2 0 0 NA NA NA NA NA
#> 3 NA NA 0 0 0 NA NA
#> 4 NA NA 1 1 1 1 1
#> 5 NA NA 1 1 1 1 1
#> 6 NA NA 0 0 0 0 0
#> 7 0 NA NA NA NA NA NA
#> 8 0 0 NA NA NA NA NA
#> 9 NA NA 0 1 1 1 1
#> 10 NA NA 1 1 1 1 1
#> 11 NA NA 1 NA NA NA NA
#> 12 1 1 NA NA NA NA NA
#> 13 NA NA 1 1 1 1 1
#> 14 NA NA 0 0 0 0 0
#> 15 NA NA 0 1 NA NA NA
#> 16 NA NA 0 1 NA NA 1
#> 17 0 NA NA NA NA NA NA
#> 18 1 NA NA NA NA NA NA
#> 19 NA NA 0 0 0 0 1
#> 20 NA NA 1 1 1 1 1
#> 21 NA NA 1 1 NA NA NA
#> 22 NA NA 0 1 NA NA NA
#> 23 NA NA 0 0 0 1 NA
#> 24 NA NA 1 1 1 1 NA
#> 25 NA NA 0 0 0 0 0
#> 26 NA NA 0 NA NA NA NA
#> 27 NA NA 0 NA NA NA NA
#> 28 NA NA 0 NA NA NA NA
#> 29 1 1 1 NA NA NA NA
#> 30 NA 1 1 NA NA NA NA
t(apply(m, 1, function(x) ifelse(is.na(x), NA, seq_along(x) - match(1, x, nomatch = 0))))
#> 1 2 4 5 6 7 8
#> 1 -1 0 NA NA NA NA NA
#> 2 1 2 NA NA NA NA NA
#> 3 NA NA 3 4 5 NA NA
#> 4 NA NA 0 1 2 3 4
#> 5 NA NA 0 1 2 3 4
#> 6 NA NA 3 4 5 6 7
#> 7 1 NA NA NA NA NA NA
#> 8 1 2 NA NA NA NA NA
#> 9 NA NA -1 0 1 2 3
#> 10 NA NA 0 1 2 3 4
#> 11 NA NA 0 NA NA NA NA
#> 12 0 1 NA NA NA NA NA
#> 13 NA NA 0 1 2 3 4
#> 14 NA NA 3 4 5 6 7
#> 15 NA NA -1 0 NA NA NA
#> 16 NA NA -1 0 NA NA 3
#> 17 1 NA NA NA NA NA NA
#> 18 0 NA NA NA NA NA NA
#> 19 NA NA -4 -3 -2 -1 0
#> 20 NA NA 0 1 2 3 4
#> 21 NA NA 0 1 NA NA NA
#> 22 NA NA -1 0 NA NA NA
#> 23 NA NA -3 -2 -1 0 NA
#> 24 NA NA 0 1 2 3 NA
#> 25 NA NA 3 4 5 6 7
#> 26 NA NA 3 NA NA NA NA
#> 27 NA NA 3 NA NA NA NA
#> 28 NA NA 3 NA NA NA NA
#> 29 0 1 2 NA NA NA NA
#> 30 NA 0 1 NA NA NA NA