给出一个向量:
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
感谢您的帮助!
答案 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