如何在R中动态创建矩阵?

时间:2017-04-25 20:28:43

标签: r

我需要在R中生成逻辑矩阵。矩阵的维度是动态的,矩阵的列名和行名都来自向量。

vector1 <- c(a,b,c,d)
vector2 <- c(a,c,e,f,g)
vector3 <- c(d,f,g,z)

依旧......

迭代每个向量,将向量名称设置为行名称。如果在矩阵列名称中找到向量值,则将相应的矩阵单元格值设置为1,否则将新列添加到矩阵并将值1指定给单元格。 矩阵值是1/0,它应该像这样工作

        a  b  c  d  e  f  g  z
vector1 1  1  1  1  0  0  0  0
vector2 1  0  1  0  1  1  1  0
vector3 0  0  0  1  0  1  1  1

这只是一个简单的演示,实际上每个矢量的大小非常大。

2 个答案:

答案 0 :(得分:4)

#DATA
vector1 = c("a", "b", "c", "d")
vector2 = c("a", "c", "e", "f", "g")
vector3 = c("d", "f", "g", "z")

#Get all vectors in a list
temp = mget(paste("vector", 1:3, sep = ""))
           #You could do sequence(length(ls(pattern = "vector"))) instead of 1:3

#1) As pointed out in the comments by akrun, use `mtabulate` of `qdapTools` package
library(qdapTools)
mtabulate(temp)
#        a b c d e f g z
#vector1 1 1 1 1 0 0 0 0
#vector2 1 0 1 0 1 1 1 0
#vector3 0 0 0 1 0 1 1 1

#2) Or if you want to do it in base R

  #2-i) as pointed out by akrun
  table(stack(temp)[2:1]) #also check data.frame(unclass(table(stack(temp)[2:1])))
  #         values
  #ind       a b c d e f g z
  #  vector1 1 1 1 1 0 0 0 0
  #  vector2 1 0 1 0 1 1 1 0
  #  vector3 0 0 0 1 0 1 1 1

  #2-ii)
  #Get the unique values
  temp2 = unique(unlist(temp))

  setNames(object = data.frame(do.call(rbind, lapply(temp, function(a)
      as.numeric(temp2 %in% a)))),
      nm = temp2)
  #        a b c d e f g z
  #vector1 1 1 1 1 0 0 0 0
  #vector2 1 0 1 0 1 1 1 0
  #vector3 0 0 0 1 0 1 1 1

答案 1 :(得分:1)

虽然迟到了,我想建议两种不同的方法

  • 存储和读取动态的“稀疏矩阵”信息
  • 并使用dcast()创建矩阵。

存储和读取动态矩阵信息

OP已经公开了矩阵的列名和行名来自向量,而实际上每个向量的大小非常大。她提供了样本数据

vector1 <- c(a,b,c,d)
vector2 <- c(a,c,e,f,g)
vector3 <- c(d,f,g,z)

其中列名称无有效字符串。每个列名都需要用引号括起来(如in the other answer所做),这对于大型向量来说是乏味的。

因此,我建议以紧凑且方便的形式存储矩阵的行名rn和列名cn

rn      cn
vector1 a,b,c,d
vector2 a,c,e,f,g
vector3 d,f,g,z

在文件或字符串中。 cn包含以逗号分隔的矩阵列的名称。

可以读取这种“稀疏矩阵定义”,例如,

library(data.table)
sparse <- fread("
rn      cn
vector1 a,b,c,d
vector2 a,c,e,f,g
vector3 d,f,g,z
")

创建矩阵

这需要两个步骤。首先,需要为每个行名提取列名。这是通过使用strsplit()

来完成的
long <- sparse[, strsplit(cn, ","), by = rn]

long
#         rn V1
# 1: vector1  a
# 2: vector1  b
# 3: vector1  c
# 4: vector1  d
# 5: vector2  a
# 6: vector2  c
# 7: vector2  e
# 8: vector2  f
# 9: vector2  g
#10: vector3  d
#11: vector3  f
#12: vector3  g
#13: vector3  z

长格式返回稀疏矩阵信息。请注意,V1现在包含矩阵列的名称作为字符,使我们无需手动将它们包装在引号中。

现在,OP期望宽格式的结果01表示相应列的缺席或存在。重塑可以使用dcast()

完成
result <- dcast(long, rn ~ V1, length)

result
#        rn a b c d e f g z
#1: vector1 1 1 1 1 0 0 0 0
#2: vector2 1 0 1 0 1 1 1 0
#3: vector3 0 0 0 1 0 1 1 1

或者,以更复杂的形式:

result <- dcast(sparse[, strsplit(cn, ","), by = rn], rn ~ V1, length)

现在,结果可以从data.table转换为具有适当行名的矩阵:

mat <- as.matrix(result[, .SD, .SDcols = -c("rn")])
rownames(mat) <- result[, rn]
mat
#        a b c d e f g z
#vector1 1 1 1 1 0 0 0 0
#vector2 1 0 1 0 1 1 1 0
#vector3 0 0 0 1 0 1 1 1