矢量到元素之间的差异矩阵

时间:2013-11-18 02:11:06

标签: r vector matrix

给出一个向量:

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

感谢您的帮助!

4 个答案:

答案 0 :(得分:15)

这通常使用outer完成。

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

有关详细信息,请参阅?outer

答案 1 :(得分:2)

可能的解决方案:

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

甚至

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

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

答案 2 :(得分:1)

我会使用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 :(得分: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