【问题标题】:build array of uneven matrices in r在r中构建不均匀矩阵数组
【发布时间】:2020-12-04 02:28:44
【问题描述】:

我正在尝试构建一个包含不均匀矩阵的数组。最终目标是计算所有矩阵的平均值以创建最终矩阵。当矩阵具有相同的大小和相同的暗名时,我的代码有效。现在我正在扩展输入,但问题是它们的名称并不相同。

这是以前工作的简化代码:

labs <- c("A", "B", "C", "D")

dists <- array(0,
    c(length(labs),
        length(labs),
        length(input)),
    dimnames=list(labs, labs))

for (i in 1:length(input)) {
    d <- input[[i]] #short cut to replace bunch of code to create input 
    #class(d) "matrix" "arrary"
    #rownames(d) and colnames(d) would be A, B, C, D in a complete matrix.
    dists[,, i] <- d[labs, labs] #Now ERRORS HERE with uneven d
    }

avg_dists <- apply(dists, c(1, 2), mean)

基于this 帖子,也许我需要使用 abind 但不确定如何在上面的循环中应用它。 我基本上尝试使用最大/完整的实验室来构建初始数组,就像在这个 post 中一样,但是它的错误下标超出范围并且再次不确定如何在此处的循环中应用它。

非常感谢您的帮助。

编辑:根据下面的评论,我添加了一些示例输入数据:

a <- matrix(1:4, 2, 2)
b <- matrix(1:9, 3, 3)
c <- matrix(1:8, 4, 4)
colnames(c) <- c("A", "B", "C", "D")
rownames(c) <- c("A", "B", "C", "D")
colnames(b) <- c("A", "B", "C")
rownames(b) <- c("A", "B", "C")
colnames(a) <- c("A", "B")
rownames(a) <- c("A", "B")

input <- list(a,b,c)

所需的输出将是一个平均距离矩阵(输入是距离矩阵),如下所示:

<avg_dists

  A B   C  D
A 1 4   4  5
B 2 5   6  6
C 3 6.5 6 7
D 4 8   4 8

【问题讨论】:

  • 如果没有您所面临错误的实际示例,将很难提供帮助。
  • @RonakShah。对不起,我的帖子不清楚。我在上面提到:由于实验室不等,我得到的错误是dists[,, i] &lt;- d[labs, labs] 行的“下标越界”。
  • 好的..您正在寻找共享的input 的最终输出(带有值)是什么?
  • @RonakShah 我已经添加了所需的输出 - 这将是最初共享的最后一行代码产生的平均值矩阵:avg_dists &lt;- apply(dists, c(1, 2), mean)

标签: r arrays matrix


【解决方案1】:

您可以像这样展平矩阵列表

flatinput <- do.call(rbind, lapply(input, as.data.frame.table, responseName = "dist"))

展平后

> head(flatinput)

  Var1 Var2 dist
1    A    A    1
2    B    A    2
3    A    B    3
4    B    B    4
5    A    A    1
6    B    A    2

那就tapply

tapply(flatinput$dist, unname(flatinput[, -3L]), mean)

输出

  A   B C D
A 1 4.0 4 5
B 2 5.0 5 6
C 3 6.5 6 7
D 4 8.0 4 8

【讨论】:

  • 好的,哇,这太棒了,让我可以简单地编写所有其余的代码。非常感谢。
【解决方案2】:

您可以在每个列表中添加一个行名作为新列,merge 将它们放在一起,并根据rowid 获取所有列中的mean

aggregate(.~rowid, Reduce(function(x, y) merge(x, y, all = TRUE), 
       lapply(input, function(x) transform(data.frame(x), rowid = rownames(x)))),
              mean, na.rm = TRUE, na.action = na.pass)

#  rowid A   B C D
#1     A 1 4.0 4 5
#2     B 2 5.0 5 6
#3     C 3 6.5 6 7
#4     D 4 8.0 4 8

【讨论】:

  • 也非常感谢!不幸的是,我的实际数据太大了,在完成之前挂了一段时间。不过谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多