Создайте матрицу нулей и единиц из R

#r #matrix

Вопрос:

Я хочу создать матрицу из 0 и 1 на основе следующих данных.

     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
 

Итак, основываясь на данных, мне нужно создать матрицу 6X3, где первый столбец должен быть (1,1,1,0,0,0), а второй столбец должен быть (0,0,0,1,1,0) и так далее.

Можете ли вы предложить что-нибудь для этого?

Спасибо

Ответ №1:

Мы можем использовать model.matrix в base R

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

-выход

 #   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
 

Или использовать table

 with(data_toy, table(seq_along(id), id))
 

Комментарии:

1. Элегантное решение!

Ответ №2:

 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
 

или

 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
 

добавление as.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
 

Комментарии:

1. Я знал, что ты придумаешь dplyr ответ, ха-ха 🙂

2. @ThomasIsCoding, ЛОЛ, на самом деле я выучил R неправильно, я начал с R4ds Уикхема. Вот почему моя база в tidyverse и baseR, напротив, является для меня новым пакетом. 😀

Ответ №3:

Еще один базовый вариант R

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

дает

      [,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
 

Комментарии:

1. Я думаю, (не уверен) length(unique(id)) было бы лучше вместо max(id) того, чтобы также id иметь буквенно-цифровой тип.

2. @AnilGoyal Да, вы правы. Это безопасно иметь length(unique(id)) . Большое спасибо!

Ответ №4:

 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