在R中将树状列表转换为反向下三角矩阵

5

我应该如何进行转换?

m = list(1,2:3,4:6,7:10)

为了

     [,1] [,2] [,3] [,4]
[1,]    0    0    0   10
[2,]    0    0    6    9
[3,]    0    3    5    8
[4,]    1    2    4    7

感激您能提供一些想法或指导!如果问题太幼稚或需要额外信息,谢谢您的耐心(我很乐意提供)。
4个回答

7

我将使用基础的R方法往前推进。

# Create matrix with dimensions defined by the length of your list 
mat <- matrix(0, length(m), length(m)) 
# Fill in desired order
mat[upper.tri(mat, TRUE)] <- unlist(m)
# Order rows 
mat[length(m):1, ]

因为你的答案好了100倍。将数字转换为字符再转回数字并不是正确的做法。 - Rich Scriven
是的,也许吧,但我认为介绍那些隐藏在包中不太知名的函数是很有用的(否则我永远不会知道它们存在!) - user20650

4

1)lapply之下,将m的每个组件附加n个零,而sapply则取m的每个组件的前n个元素,并将结果重新整形成矩阵。最后,我们颠倒了结果矩阵的行顺序。即使m没有定义三角形矩阵,这也可以工作:

n <- length(m)
sapply(lapply(m, c, numeric(n)), head, n)[n:1, ]

提供:

     [,1] [,2] [,3] [,4]
[1,]    0    0    0   10
[2,]    0    0    6    9
[3,]    0    3    5    8
[4,]    1    2    4    7

如果 n 可以为零,则将 n:1 替换为 rev(seq_len(n))

2) 直接使用 sapply 也可以。它会将每个反转的 m 组件前置适当数量的零,并重新调整为矩阵形式:

sapply(m, function(v) c(numeric(n - length(v)), rev(v)))

1
这里有另一个可考虑的选项。它使用lengths来计算最长向量的长度,然后使用vapply,自动简化为矩阵(类似于sapply,但速度更快)。
len <- max(lengths(m))           ## What's the longest vector in m?
vapply(m, function(x) {
  length(x) <- len               ## Make all vectors the same length
  rev(replace(x, is.na(x), 0))   ## Replace NA with 0 and reverse
}, numeric(len))
#      [,1] [,2] [,3] [,4]
# [1,]    0    0    0   10
# [2,]    0    0    6    9
# [3,]    0    3    5    8
# [4,]    1    2    4    7

1
如果您正在使用稀疏矩阵(来自Matrix包),这些也可以工作:
> N <- lengths(m)
> sparseMatrix(i=1+length(m)-sequence(N), j=rep.int(N,N), x=unlist(m))
4 x 4 sparse Matrix of class "dgCMatrix"

[1,] . . . 10
[2,] . . 6  9
[3,] . 3 5  8
[4,] 1 2 4  7

这与上三角矩阵的成语几乎相同:

> sparseMatrix(i=sequence(N), j=rep.int(N,N), x=unlist(m))
4 x 4 sparse Matrix of class "dgCMatrix"

[1,] 1 2 4  7
[2,] . 3 5  8
[3,] . . 6  9
[4,] . . . 10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接