Create a matrix of zeros and ones from R

Viewed 431

I want to create a matrix of 0s and 1s based on the following data.

    id <-c(1,1,1,2,2,3)
    x<- c(5,7,8,2,6,5)
    data_toy <- data.frame(id,x)
   data_toy%>% count(id) 

> data_toy%>% count(id) 
  id n
1  1 3
2  2 2
3  3 1

So based on the data, I need to create a 6X3 matrix where first column should be (1,1,1,0,0,0) and second column should be (0,0,0,1,1,0) so on.

Can you suggest anything to do this?

Thank you

4 Answers

We can use model.matrix in base R

model.matrix(~ factor(id) - 1, data_toy)

-output

#   factor(id)1 factor(id)2 factor(id)3
#1           1           0           0
#2           1           0           0
#3           1           0           0
#4           0           1           0
#5           0           1           0
#6           0           0           1

Or use table

with(data_toy, table(seq_along(id), id))
id <-c(1,1,1,2,2,3)
x<- c(5,7,8,2,6,5)
data_toy <- data.frame(id,x)
library(tidyverse)
data_toy %>% count(id) %>% mutate(id1 = id) %>%
  pivot_wider(id_cols = c(id, n), names_from = id1, values_from = id1, values_fn = length, values_fill = 0) %>%
  uncount(n)
#> # A tibble: 6 x 4
#>      id   `1`   `2`   `3`
#>   <dbl> <int> <int> <int>
#> 1     1     1     0     0
#> 2     1     1     0     0
#> 3     1     1     0     0
#> 4     2     0     1     0
#> 5     2     0     1     0
#> 6     3     0     0     1

OR

data_toy %>% count(id) %>% 
  pivot_wider(id_cols = n, names_from = id, values_from = id, values_fn = length, values_fill = 0) %>%
  uncount(n)

# A tibble: 6 x 3
    `1`   `2`   `3`
  <int> <int> <int>
1     1     0     0
2     1     0     0
3     1     0     0
4     0     1     0
5     0     1     0
6     0     0     1

adding as.matrix at the end will convert it to matrix

data_toy %>% count(id) %>% 
  pivot_wider(id_cols = n, names_from = id, values_from = id, values_fn = length, values_fill = 0) %>%
  uncount(n) %>% as.matrix()

     1 2 3
[1,] 1 0 0
[2,] 1 0 0
[3,] 1 0 0
[4,] 0 1 0
[5,] 0 1 0
[6,] 0 0 1

Another base R option

with(
  data_toy,
  replace(matrix(
    0,
    length(id), length(unique(id))
  ), cbind(seq_along(id), id), 1)
)

gives

     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    1    0    0
[3,]    1    0    0
[4,]    0    1    0
[5,]    0    1    0
[6,]    0    0    1
sapply(unique(data_toy$id), function(x) as.integer(data_toy$id == x))

     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    1    0    0
[3,]    1    0    0
[4,]    0    1    0
[5,]    0    1    0
[6,]    0    0    1
Related