我想在给定相关向量的情况下创建相关矩阵,相关向量是相关矩阵的上(或下)三角矩阵。
目标是转换此向量
这个相关矩阵在对角线上有1s。
你知道是否有一种方法创建一个矩阵,给定对角线上方的三角形并将对角线设置为1?
答案 0 :(得分:6)
我不知道是否有自动方法可以做到这一点,但扩展我的评论:
myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
mempty <- matrix(0, nrow = 4, ncol = 4)
mindex <- matrix(1:16, nrow = 4, ncol = 4)
mempty[mindex[upper.tri(mindex)]] <- myvec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
diag(mempty) <- 1
mempty
# [,1] [,2] [,3] [,4]
# [1,] 1.00 -0.55 -0.48 0.47
# [2,] -0.55 1.00 0.66 -0.38
# [3,] -0.48 0.66 1.00 -0.46
# [4,] 0.47 -0.38 -0.46 1.00
这是一个快速入侵的功能。我希望我的所有数学步骤都是正确的!
vec2symmat <- function(invec, diag = 1, byrow = TRUE) {
Nrow <- ceiling(sqrt(2*length(invec)))
if (!sqrt(length(invec)*2 + Nrow) %% 1 == 0) {
stop("invec is wrong length to create a square symmetrical matrix")
}
mempty <- matrix(0, nrow = Nrow, ncol = Nrow)
mindex <- matrix(sequence(Nrow^2), nrow = Nrow, ncol = Nrow, byrow = byrow)
if (isTRUE(byrow)) {
mempty[mindex[lower.tri(mindex)]] <- invec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
} else {
mempty[mindex[upper.tri(mindex)]] <- invec
mempty[lower.tri(mempty)] <- t(mempty)[lower.tri(t(mempty))]
}
diag(mempty) <- diag
mempty
}
这里对角线的值不同。
vec2symmat(1:3, diag = NA)
# [,1] [,2] [,3]
# [1,] NA 1 2
# [2,] 1 NA 3
# [3,] 2 3 NA
如果您尝试提供无法创建方阵的数据,则会出现错误消息。
vec2symmat(1:4)
# Error in vec2symmat(1:4) :
# invec is wrong length to create a square symmetrical matrix
并且,使用默认设置。
vec2symmat(1:10)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 2 3 4
# [2,] 1 1 5 6 7
# [3,] 2 5 1 8 9
# [4,] 3 6 8 1 10
# [5,] 4 7 9 10 1
答案 1 :(得分:6)
您可以说服R您的矢量是距离物体,然后使用as.matrix
进行转换:
> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> class(myvec) <- 'dist'
> attr(myvec,'Size') <- 4
> as.matrix(myvec)
1 2 3 4
1 0.00 -0.55 -0.48 0.66
2 -0.55 0.00 0.47 -0.38
3 -0.48 0.47 0.00 -0.46
4 0.66 -0.38 -0.46 0.00
@AnandaMahto答案的变体(类似于上面使用的内部):
> myvec <- c(-.55, -.48, .66, .47, -.38, -.46)
> mycor <- matrix(0,4,4)
> mycor[ col(mycor) < row(mycor) ] <- myvec
> mycor <- mycor + t(mycor)
> diag(mycor) <- 1
> mycor
[,1] [,2] [,3] [,4]
[1,] 1.00 -0.55 -0.48 0.66
[2,] -0.55 1.00 0.47 -0.38
[3,] -0.48 0.47 1.00 -0.46
[4,] 0.66 -0.38 -0.46 1.00
答案 2 :(得分:3)
一些辅助函数的答案可能对其他问题有用:
`lower.tri<-` <- function(x,value){
x[lower.tri(x)] <- value
x
}
`upper.tri<-` <- function(x,value){
y <- t(x)
lower.tri(y) <- value
t(y)
}
vec2mat <- function(r){
n <- (1+sqrt(1+8*length(r)))/2
x <- diag(1,n)
lower.tri(x) <- upper.tri(x) <- r
x
}
编辑:请注意upper.tri<-
并非只是通过将“lower”替换为lower.tri<-
中的“upper”来获得。这会使结果不对称。
结果:
vec2mat(c(-0.55, -0.48, 0.66, 0.47, -0.38, -0.46))
[,1] [,2] [,3] [,4]
[1,] 1.00 -0.55 -0.48 0.66
[2,] -0.55 1.00 0.47 -0.38
[3,] -0.48 0.47 1.00 -0.46
[4,] 0.66 -0.38 -0.46 1.00
答案 3 :(得分:0)
在任何编程语言中,我认为你只需要使用几个嵌套的for循环:
假设:
Vector R; //我将使用圆括号R(3)表示基于第3个元素的圆括号。 //(以零基数组的语言存储在内存位置R [2]中) int N;
矩阵M =矩阵(N,N); //矩阵对象的新实例,或者你可以只使用数组。
int i,j,k;
k=1;
for(i=1;i<N;i++)
{
M(i,i)=1;
for(j=i+1,j<=N;j++)
{
M(i,j)=M(j,i)=R[k];
k=k+1;
}
}
这里我假设您知道N是什么,并且您有基本对象,如矢量和矩阵可用。 (如果没有,它们是编写第一个'对象'的一个很好的示例问题)复杂的数据结构,如矢量,矩阵,复数和直方图都是理想的对象。考虑面向对象的科学工作编程的正确方法是使用对象来教你的编译器理解你想要在实际工作中使用的高级数据类型......这些对象用于创建自定义编程语言非常适合您的工作类型。任何通常有用的东西都应该进入对象,因为这些对象将会成长并发展成为可重用的代码库。
顶级代码可以是一个非常强大,易于阅读和清洁的应用程序(因为在对象中完成了大量的细节工作)或者,对于快速和脏的编码,顶级代码是你的地方把所有脆弱的黑客。因为它不是可以重复使用的。
一旦你得到这样的调试,你只需要创建一个矩阵构造函数,它将相关向量和N作为参数,并为你初始化矩阵。
当然,如果您正在使用一些高级图形数学程序,该程序对您可以使用的内容有强烈的意见。不能用matricies和向量,那么你必须将向量乘以N个matricies来生成最终matric的每个列向量。 (或者阅读手册)
至少,你必须告诉我们数学课程叫什么......:)