将数字列表扩展为矩阵(包含 n 个值的列表乘以 n x n 矩阵)
Expanding a list of numbers into a matrix (list with n values to multiply to a n x n matrix)
我有一组数字,我想将其展开成一个矩阵。
列表中有 4 个值,我想将其扩展为 4x4 矩阵。
这是一些示例数据
freq <- c(627,449,813,111)
我想把它展开成一个矩阵,这样就变成了这样。
抱歉,我刚刚复制并粘贴了数据,因此它不是 R 输出,但希望它有助于理解这个想法。
1 2 3 4 Total
1 197 141 255 35 627
2 141 101 183 25 449
3 255 183 330 45 813
4 35 25 45 6 111
627 449 813 111 2000
单元格是(行总计)x(列总计)/(table 总计)的乘积。 1,1 中的值 = (627 x 627)/2000 = 197。2,1 中的值 = (627 x 449)/2000 = 141,依此类推。
是否有创建该矩阵的函数?我会尝试通过循环来完成,但希望有一个函数或矩阵计算技巧可以更有效地做到这一点?抱歉,如果我没有很好地表达上述内容,我们将不胜感激。谢谢
freq <- c(627,449,813,111)
round(outer(freq, freq)/sum(freq))
#> [,1] [,2] [,3] [,4]
#> [1,] 197 141 255 35
#> [2,] 141 101 183 25
#> [3,] 255 183 330 45
#> [4,] 35 25 45 6
这在这里并不重要,但最好避免像 outer(x, x) / sum(x)
这样的结构,而使用像 tcrossprod(x / sqrt(sum(x)))
:
这样的结构
round(tcrossprod(freq / sqrt(sum(freq))))
## [,1] [,2] [,3] [,4]
## [1,] 197 141 255 35
## [2,] 141 101 183 25
## [3,] 255 183 330 45
## [4,] 35 25 45 6
outer
方法存在一些问题:
outer(x, x)
在内部计算 tcrossprod(as.vector(x), as.vector(x))
。如果 x
已经是向量,那么 as.vector
调用和 outer
内部发生的所有其他事情都是完全多余的。 as.vector
调用实际上比冗余更糟糕:如果 x
有任何属性,那么 as.vector(x)
需要 x
. 的深层副本
- 天真地做
A <- outer(x, x); A / sum(x)
需要R为两个n
-by-n
矩阵分配内存。对于足够大的 n
,即使不是不可能,也是非常浪费的。如果直接计算 outer(x, x) / sum(x)
,R 足够聪明,可以避免第二次分配。然而,这样的优化是低级的,有很多陷阱,甚至没有记录在 ?Arithmetic
中,因此依赖它们可能是不安全的。
如果 x
的元素非常(非常)小或大,outer(x, x)
会导致下溢或溢出。
tcrossprod(x / sqrt(sum(x)))
通过在计算外积 之前缩放 x
并删除 outer
的所有冗余来避免所有这些问题.
我有一组数字,我想将其展开成一个矩阵。 列表中有 4 个值,我想将其扩展为 4x4 矩阵。 这是一些示例数据
freq <- c(627,449,813,111)
我想把它展开成一个矩阵,这样就变成了这样。 抱歉,我刚刚复制并粘贴了数据,因此它不是 R 输出,但希望它有助于理解这个想法。
1 2 3 4 Total
1 197 141 255 35 627
2 141 101 183 25 449
3 255 183 330 45 813
4 35 25 45 6 111
627 449 813 111 2000
单元格是(行总计)x(列总计)/(table 总计)的乘积。 1,1 中的值 = (627 x 627)/2000 = 197。2,1 中的值 = (627 x 449)/2000 = 141,依此类推。
是否有创建该矩阵的函数?我会尝试通过循环来完成,但希望有一个函数或矩阵计算技巧可以更有效地做到这一点?抱歉,如果我没有很好地表达上述内容,我们将不胜感激。谢谢
freq <- c(627,449,813,111)
round(outer(freq, freq)/sum(freq))
#> [,1] [,2] [,3] [,4]
#> [1,] 197 141 255 35
#> [2,] 141 101 183 25
#> [3,] 255 183 330 45
#> [4,] 35 25 45 6
这在这里并不重要,但最好避免像 outer(x, x) / sum(x)
这样的结构,而使用像 tcrossprod(x / sqrt(sum(x)))
:
round(tcrossprod(freq / sqrt(sum(freq))))
## [,1] [,2] [,3] [,4]
## [1,] 197 141 255 35
## [2,] 141 101 183 25
## [3,] 255 183 330 45
## [4,] 35 25 45 6
outer
方法存在一些问题:
outer(x, x)
在内部计算tcrossprod(as.vector(x), as.vector(x))
。如果x
已经是向量,那么as.vector
调用和outer
内部发生的所有其他事情都是完全多余的。as.vector
调用实际上比冗余更糟糕:如果x
有任何属性,那么as.vector(x)
需要x
. 的深层副本
- 天真地做
A <- outer(x, x); A / sum(x)
需要R为两个n
-by-n
矩阵分配内存。对于足够大的n
,即使不是不可能,也是非常浪费的。如果直接计算outer(x, x) / sum(x)
,R 足够聪明,可以避免第二次分配。然而,这样的优化是低级的,有很多陷阱,甚至没有记录在?Arithmetic
中,因此依赖它们可能是不安全的。
如果 outer(x, x)
会导致下溢或溢出。
x
的元素非常(非常)小或大,tcrossprod(x / sqrt(sum(x)))
通过在计算外积 之前缩放 x
并删除 outer
的所有冗余来避免所有这些问题.