简体   繁体   中英

R, Trying to transform a vector of integer to a specific binary Matrix

I would like to transform a vector of integer such:

vector = c(0,6,1,8,5,4,2)

length(vector) = 7

max(vector) = 8

into a matrix m of nrow = length(vector) and ncol = max(vector):

m = 

0 0 0 0 0 0 0 0

1 1 1 1 1 1 0 0

1 0 0 0 0 0 0 0

1 1 1 1 1 1 1 1

1 1 1 1 1 0 0 0

1 1 1 1 0 0 0 0

1 1 0 0 0 0 0 0

It's just an example of what I am trying to do. I intend that the function work with every vector of integer.

I tried to used the function mapply(rep, 1, vector) but I obtained a list and I didn't succeed to convert it into a matrix...

It would be very useful for me if someone can help me.

Best Regards,

Maxime

If you use c(rep(1, x), rep(0, max(vector-x)) on each element of your variable vector you get the desired binary results. Looping that with sapply even returns a matrix. You only need to transpose it afterwards and you get your result.

vector = c(0,6,1,8,5,4,2)
result <- t(sapply(vector, function(x) c(rep(1, x), rep(0, max(vector)-x))))

is.matrix(result)
#> [1] TRUE

result
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,]    0    0    0    0    0    0    0    0
#> [2,]    1    1    1    1    1    1    0    0
#> [3,]    1    0    0    0    0    0    0    0
#> [4,]    1    1    1    1    1    1    1    1
#> [5,]    1    1    1    1    1    0    0    0
#> [6,]    1    1    1    1    0    0    0    0
#> [7,]    1    1    0    0    0    0    0    0

Putting that into a function is easy:

  binaryMatrix <- function(v) {
    t(sapply(v, function(x) c(rep(1, x), rep(0, max(v)-x))))
  }
  binaryMatrix(vector)
  # same result as before

Created on 2021-02-14 by the reprex package (v1.0.0)

Another straightforward approach would be to exploit matrix sub-assignment using row/column indices in a matrix form (see, also, ?Extract ).

Define a matrix of 0s:

x = c(0, 6, 1, 8, 5, 4, 2)
m = matrix(0L, nrow = length(x), ncol = max(x))

And fill with 1s:

i = rep(seq_along(x), x)  ## row indices of 1s
j = sequence(x)           ## column indices of 1s
ij = cbind(i, j)          
m[ij] = 1L

m
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#[1,]    0    0    0    0    0    0    0    0
#[2,]    1    1    1    1    1    1    0    0
#[3,]    1    0    0    0    0    0    0    0
#[4,]    1    1    1    1    1    1    1    1
#[5,]    1    1    1    1    1    0    0    0
#[6,]    1    1    1    1    0    0    0    0
#[7,]    1    1    0    0    0    0    0    0
        

Assuming that all values in the vector are non-negative integers, you can define the following function

transformVectorToMatrix <- function(v) {
  
  nrOfCols <- max(v)
  
  zeroRow <- integer(nrOfCols)
  
  do.call("rbind",lapply(v,function(nrOfOnes) {
    if(nrOfOnes==0) return(zeroRow)
    if(nrOfOnes==nrOfCols) return(zeroRow+1)
    c(integer(nrOfOnes)+1,integer(nrOfCols-nrOfOnes))
  }))
}

and finally do

m = transformVectorToMatrix(vector)

to get your desired binary matrix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM