【问题标题】:Vector to Matrix of Differences between elements向量到元素之间的差异矩阵
【发布时间】:2013-12-01 01:55:10
【问题描述】:

给定一个向量:

vec <-1:5

什么是创建矩阵的有效方法,其中向量分量之间的差异显示在一个矩阵中,一个差异矩阵,如果你愿意的话。我显然可以用两个 for 循环来做到这一点,但我需要用更大的数据集来做到这一点。我正在尝试为这个矩阵创建一个术语,但我没有找到它。结果如下所示。

m<-matrix(c(NA), ncol=5, nrow=5, byrow=TRUE)
rownames(m)<-1:5;colnames(m)<-1:5
for(i in 1:5){for(j in 1:5){m[i,j]<-(as.numeric(rownames(m)[i])-as.numeric(rownames(m)[j]))}}
m

感谢您的帮助!

【问题讨论】:

    标签: r vector matrix


    【解决方案1】:

    这里的答案可能很好地完成了这项工作,但我最终只是将一个应该使用一些简单的蛮力基本逻辑来完成此任务的函数组合在一起。我想我会在这里分享,以防其他人可能会从中受益。

    diffmat = function(x){
      D = matrix(as.numeric(NA), NROW(x), NROW(x))
      for (i in 1:NROW(x)){
        d = x[[i]] - x[-i]
        D[i,-i] = d
      }
      if (!all(is.na(diag(D)))){
        stop("Not all diagonal elements zero")
      }
      diag(D) = 0
      if (!is.null(names(x))) colnames(D) = rownames(D) = names(x)
      return(D)
    }
    

    使用示例:

    > x = runif(5)
    > names(x) = LETTERS[1:length(x)]
    > x
             A          B          C          D          E
    0.22095809 0.16006394 0.07402069 0.29795031 0.16199981
    > diffmat(x)
                A            B          C           D            E
    A  0.00000000  0.060894142 0.14693739 -0.07699223  0.058958278
    B -0.06089414  0.000000000 0.08604325 -0.13788637 -0.001935864
    C -0.14693739 -0.086043252 0.00000000 -0.22392962 -0.087979116
    D  0.07699223  0.137886368 0.22392962  0.00000000  0.135950504
    E -0.05895828  0.001935864 0.08797912 -0.13595050  0.000000000
    

    【讨论】:

      【解决方案2】:

      我会使用vapply 函数——它并不比matrix 方法慢多少……而且我不喜欢outer 返回输出的方式。见下文:

      dd <- 1:5
      vapply(seq_along(dd), 
             FUN = function(i, X) X[[i]] - X, 
             FUN.VALUE = numeric(length(dd)), 
             dd)
      
      vf <- function() vapply(seq_along(dd), 
                              FUN = function(i, X) X[[i]] - X, 
                              FUN.VALUE = numeric(length(dd)), 
                              dd)
      
      mf <- function() matrix(dd, length(dd), length(dd), byrow=T) - 
                       matrix(dd, length(dd), length(dd), byrow=FALSE)
      
      microbenchmark(vf(), mf(), times = 1e4)
      
      Unit: microseconds
       expr    min     lq      mean median     uq     max neval cld
       vf() 20.527 22.037 26.678118 22.942 24.149 785.434  1000   b
       mf()  4.227  4.831  6.343785  5.132  5.434 503.499  1000  a 
      

      【讨论】:

        【解决方案3】:

        这通常使用outer 完成。

        outer(1:5, 1:5, '-')
        

        详情请见?outer

        【讨论】:

          【解决方案4】:

          一个可能的解决方案:

          matrix(vec, 5, 5, byrow=TRUE) - matrix(vec, 5, 5, byrow=FALSE)
          

          甚至

          matrix(vec, 5, 5, byrow=TRUE) - vec
          

          为了简单起见,请原谅硬编码的5

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-01
            • 2014-03-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多