创建一个包含零和一的矩阵

creating a matrix with zero and one

我有这个数据:

A <- c("G", "C", "K")
B <- c("S", "B", "A")
C <- c("A", "M", "C")

我有这个矩阵。

      [A]   [B]  [C]
[1,]    T    S    R
[2,]    Y    N    C
[3,]    G    U    N
[4,]    C    Z    Q
[5,]    S    D    K
[6,]    M    A    M
[7,]    S    B    F
[8,]    K    J    A

我的想法是创建一个新的热图 8 行 x 3 列,如果行中的每列不包含变量中的字母,我给零。反之,如果变量中包含的字母对应,则为1。我会得到这样的东西:

       [A]   [B]  [C]
[1,]    0    1    0
[2,]    0    0    1
[3,]    1    0    0
[4,]    1    0    0
[5,]    0    0    0
[6,]    0    1    1
[7,]    0    1    0
[8,]    1    0    1

你能建议我一个方法吗?

一个选项是使用 mapply 同时迭代矩阵的列和 list(A, B, C)

的元素
mapply(function(col, vec) +(col %in% vec), as.data.frame(mat), list(A, B, C))
#     A B C
#[1,] 0 1 0
#[2,] 0 0 1
#[3,] 1 0 0
#[4,] 1 0 0
#[5,] 0 0 0
#[6,] 0 1 1
#[7,] 0 1 0
#[8,] 1 0 1

解释:col %in% vec 检查矩阵列向量中来自 vec 的匹配条目。一元运算符 +TRUE/FALSE 转换为 1/0.


甚至更短(感谢@thelatemail)

+mapply(`%in%`, as.data.frame(mat), list(A, B, C))

示例数据

A <- c("G", "C", "K")
B <- c("S", "B", "A")
C <- c("A", "M", "C")
mat <- matrix(c(
    "T", "Y", "G", "C", "S", "M", "S", "K",
    "S", "N", "U", "Z", "D", "A", "B", "J",
    "R", "C", "N", "Q", "K", "M", "F", "A"),
    ncol = 3)
colnames(mat) <- c("A", "B", "C")

我敢打赌有一个更简单的解决方案,但下面的方法有效。

mat1为字母矩阵

mat2 是二进制 (1,0) 矩阵。

函数 contains(x,y) 将 x(您要测试的字符向量)和 y(列名)作为字符串,然后检查该列。

A <- c("G", "C", "K")
B <- c("S", "B", "A")
C <- c("A", "M", "C")
mat1 <- matrix(c("T","S", "R", "Y", "N", "C", "G", "U", "N", "C", "Z", "Q", "S", "D", "K", "M", "A", "M", "S", "B", "F", "K", "J", "A"), nrow = 8, ncol = 3, dimnames = list(c(1:8), c("A", "B", "C")), byrow=TRUE)
mat2 <- matrix(0L, nrow = 8, ncol = 3, dimnames = list(c(1:8), c("A", "B", "C")))

row_count <- 1
contains <- function(x, y){
  for (i in mat1[,y]){
    if (i %in% x){
      mat2[row_count,y] <<- 1
    }
    row_count <<- row_count +1
  }
}


contains(A, "A")
contains(B, "B")
contains(C, "C")

希望对您有所帮助, 干杯!

我们可以使用 map2 来自 purrr

library(purrr)
+(map2_dfr(asplit(mat, 2), list(A, B, C), `%in%`))
#   A B C
#1 0 1 0
#2 0 0 1
#3 1 0 0
#4 1 0 0
#5 0 0 0
#6 0 1 1
#7 0 1 0
#8 1 0 1

对于您的矩阵 M,以下内容可能对您有所帮助:

sapply(colnames(M), function(x) as.numeric(!is.na(match(M[,x],eval(parse(text = x))))))