【问题标题】:Create a Correlation Matrix From a Correlation Vector in R从 R 中的相关向量创建相关矩阵
【发布时间】:2013-09-07 01:25:35
【问题描述】:

我想在给定相关向量的情况下创建一个相关矩阵,它是相关矩阵的上(或下)三角矩阵。

目标是变换这个向量

到这个对角线上为 1 的相关矩阵。

您知道是否有一种方法可以在给定对角线上方的三角形的情况下创建矩阵并将对角线设置为 1?

【问题讨论】:

    标签: r vector matrix correlation


    【解决方案1】:

    你可以让 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
    

    【讨论】:

    • 必须将diag(1,4) 添加到as.matrix(myvec)
    【解决方案2】:

    我不知道是否有自动的方法来做到这一点,但扩展我的评论:

    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
    

    【讨论】:

    • 还有一点问题:您的函数按列填充矩阵,如何按行填充矩阵,如上例所示?非常感谢!!!
    • @jeffrey,向矩阵添加了 byrow 参数。不过请查看 Greg Snow 的答案。
    • 工作愉快,正是我想要的。你能解释一下你的步骤吗?我是 R 的菜鸟,目前只能跟随。谢谢
    【解决方案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&lt;- 不是通过将lower.tri&lt;- 中的“lower”替换为“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
    

    【讨论】:

      【解决方案4】:

      在任何编程语言中,我认为您只需使用几个这样的嵌套 for 循环即可:

      给定:

      矢量 R; // 我将使用圆括号 R(3) 来表示基于第 3 个元素。 //(以零基数组的语言存储在内存位置 R[2] 中) 整数 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 作为参数,并为你初始化矩阵。

      当然,如果您使用的是一些高级图形数学程序,该程序对矩阵和向量可以做什么和不可以做什么有强烈的看法,那么您必须将向量乘以 N 个矩阵来生成每个最终矩阵的列向量。 (或者阅读手册)

      至少,你必须告诉我们数学程序叫什么... :)

      【讨论】:

      • 查看问题标签。那里清楚地说明了语言。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 2012-05-27
      • 2011-08-20
      • 2019-12-07
      相关资源
      最近更新 更多