Home > Net >  matrix with time to event values
matrix with time to event values

Time:11-30

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
  • Related