【问题标题】:How to create a matrix dynamically in R?如何在R中动态创建矩阵?
【发布时间】:2017-04-25 20:28:43
【问题描述】:

我需要在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

只是一个简单的demo,其实每个向量的大小都很大。

【问题讨论】:

  • 是不是一开始就有了所有的向量,还是需要为一些向量创建一个矩阵,然后再一个一个地添加?
  • 如果您可以至少 (1) 发布有效代码,(2) 正确格式化您的代码和数据,并且理想情况下 (3) 向我们展示您的内容,那就太好了试过了。
  • 不好意思,匆忙写了原帖。我尝试了多种方法,但在添加新列/行时陷入困境。

标签: r


【解决方案1】:
#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

【讨论】:

  • 或者这可以更紧凑地完成qdapTools::mtabulate(temp)base Rtable(stack(temp)[2:1])
  • 没关系。您可以将其添加到您的帖子中。因为您有时还慷慨地帮助了我:-)
  • Fwiw,我认为原来的table(stack(temp)[2:1])t(table(stack(temp))) 好。回复2-ii,如果需要 data.frame,还有 as.data.frame(unclass(z)) 其中 z 是表堆栈输出。
  • 你拯救了我的一天。谢谢一百万!
【解决方案2】:

虽然迟到了,但我想提出两种不同的方法

  • 动态“稀疏矩阵”信息的存储和读取
  • 并使用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

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    相关资源
    最近更新 更多