как преобразовать матрицу значений в двоичную матрицу

Я хотел бы преобразовать матрицу значений в матрицу "битов".

Я искал решения и нашел этой, что, похоже, является частью решения. Я попытаюсь объяснить, что я ищу. У меня есть матрица, как

> x<-matrix(1:20,5,4)
> x
     [,1] [,2] [,3] [,4]
[1,]    1    6   11   16
[2,]    2    7   12   17
[3,]    3    8   13   18
[4,]    4    9   14   19
[5,]    5   10   15   20

которые я хотел бы преобразовать в

     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  1  1 0 0 0 0 1 0 0 0  0  1  0  0  0  0  1  0  0  0  0
  2  0 1 0 0 0 0 1 0 0  0  0  1  0  0  0  0  1  0  0  0
  3  0 0 1 0 0 0 0 1 0  0  0  0  1  0  0  0  0  1  0  0
  4  0 0 0 1 0 0 0 0 1  0  0  0  0  1  0  0  0  0  1  0
  5  0 0 0 0 1 0 0 0 0  1  0  0  0  0  1  0  0  0  0  1

так для каждого значения в строке "1" в соответствующем столбце.

если я использую

> table(sequence(length(x)),t(x))

     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  1  1 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  2  0 0 0 0 0 1 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  3  0 0 0 0 0 0 0 0 0  0  1  0  0  0  0  0  0  0  0  0
  4  0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  1  0  0  0  0
  5  0 1 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  6  0 0 0 0 0 0 1 0 0  0  0  0  0  0  0  0  0  0  0  0
  7  0 0 0 0 0 0 0 0 0  0  0  1  0  0  0  0  0  0  0  0
  8  0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  1  0  0  0
  9  0 0 1 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  10 0 0 0 0 0 0 0 1 0  0  0  0  0  0  0  0  0  0  0  0
  11 0 0 0 0 0 0 0 0 0  0  0  0  1  0  0  0  0  0  0  0
  12 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  1  0  0
  13 0 0 0 1 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  14 0 0 0 0 0 0 0 0 1  0  0  0  0  0  0  0  0  0  0  0
  15 0 0 0 0 0 0 0 0 0  0  0  0  0  1  0  0  0  0  0  0
  16 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  1  0
  17 0 0 0 0 1 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0
  18 0 0 0 0 0 0 0 0 0  1  0  0  0  0  0  0  0  0  0  0
  19 0 0 0 0 0 0 0 0 0  0  0  0  0  0  1  0  0  0  0  0
  20 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  1

это близко к тому, что я ищет, но возвращает строку для каждого значения.

мне нужно будет только объединить все значения из одной строки в одну строку. Потому что

> table(x)
x
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1 

дает все значения всей таблицы, так что мне нужно сделать, чтобы получить значения для каждой строки.

4 ответов


вот еще один вариант с использованием table() функция:

table(row(x), x)
#   x
#    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#  1 1 0 0 0 0 1 0 0 0  0  1  0  0  0  0  1  0  0  0  0
#  2 0 1 0 0 0 0 1 0 0  0  0  1  0  0  0  0  1  0  0  0
#  3 0 0 1 0 0 0 0 1 0  0  0  0  1  0  0  0  0  1  0  0
#  4 0 0 0 1 0 0 0 0 1  0  0  0  0  1  0  0  0  0  1  0
#  5 0 0 0 0 1 0 0 0 0  1  0  0  0  0  1  0  0  0  0  1

    bit_x = matrix(0, nrow = nrow(x), ncol = max(x))
    for (i in 1:nrow(x)) {bit_x[i,x[i,]] = 1}

пусть

(x <- matrix(c(1, 3), 2, 2))
     [,1] [,2]
[1,]    1    1
[2,]    3    3

один подход будет

M <- matrix(0, nrow(x), max(x))
M[cbind(c(row(x)), c(x))] <- 1
M
#      [,1] [,2] [,3]
# [1,]    1    0    0
# [2,]    0    0    1

в одну строку:

replace(matrix(0, nrow(x), max(x)), cbind(c(row(x)), c(x)), 1).

следуя вашему подходу, и аналогично предложению @Psidom:

table(rep(1:nrow(x), ncol(x)), x)
#    x
#     1 3
#   1 2 0
#   2 0 2

мы можем использовать reshape2 пакета.

library(reshape2)
# At first we make the matrix you provided 
x <- matrix(1:20, 5, 4)
# then melt it based on first column
da <- melt(x, id.var = 1)
# then cast it
dat <- dcast(da, Var1 ~ value, fill = 0, fun.aggregate = length)

что дает нам этот

  Var1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1    1 1 0 0 0 0 1 0 0 0  0  1  0  0  0  0  1  0  0  0  0
2    2 0 1 0 0 0 0 1 0 0  0  0  1  0  0  0  0  1  0  0  0
3    3 0 0 1 0 0 0 0 1 0  0  0  0  1  0  0  0  0  1  0  0
4    4 0 0 0 1 0 0 0 0 1  0  0  0  0  1  0  0  0  0  1  0
5    5 0 0 0 0 1 0 0 0 0  1  0  0  0  0  1  0  0  0  0  1