基于维名称的R中矩阵的运算

时间:2018-03-05 21:43:21

标签: r matrix

我有一个对称矩阵s定义为:

s<-matrix(1:25,5)
s[lower.tri(s)] = t(s)[lower.tri(s)]
dimnames(s) <- list(LETTERS[1:5], LETTERS[1:5])
s

   A  B  C  D  E
A  1  6 11 16 21
B  6  7 12 17 22
C 11 12 13 18 23
D 16 17 18 19 24
E 21 22 23 24 25

此外,还有一个向量t定义为:

t <- seq(1,10)
names(t) <- c('C_A', 'E_A', 'E_B', 'E_C', 'E_D', 'D_A', 'D_B', 'D_C', 'C_B', 'A_B')

现在,我想将t的元素添加到s的上下三角形元素中,使t的元素名称为&#39}。 C_A&#39;已添加到s的元素中,其行和列名称为&#39; C&#39;和&#39; A&#39; (或&#39; A&#39;和&#39; C&#39;),t的元素名称为&#39; E_A&#39;已添加到s的元素中,其行和列名称为&#39; E&#39;和&#39; A&#39; (或者&#39; A&#39;和E&#39;)等。例如,s [&#39; A&#39;,&#39; B&#39;]和s [ &#39; B&#39;,&#39; A&#39;]应添加t [&#39; A_B&#39;],类似地添加所有其他非对角线元素。对角线什么都不做。

实现这一目标的优雅方式是什么?

4 个答案:

答案 0 :(得分:3)

这不是特别优雅但是:

s<-matrix(1:25,5)
s[lower.tri(s)] = t(s)[lower.tri(s)]
dimnames(s) <- list(LETTERS[1:5], LETTERS[1:5])

t <- seq(1,10)
names(t) <- c('C_A', 'E_A', 'E_B', 'E_C', 'E_D', 'D_A', 'D_B', 'D_C', 'C_B', 'A_B')

s[t(do.call(cbind, strsplit(names(t), split = "_")))] <-
  s[t(do.call(cbind, strsplit(names(t), split = "_")))] + t
s
#>    A  B  C  D  E
#> A  1 16 11 16 21
#> B  6  7 12 17 22
#> C 12 21 13 18 23
#> D 22 24 26 19 24
#> E 23 25 27 29 25

要添加[i,j]个元素,只需再次调用它,索引位置反转

s[t(do.call(cbind, strsplit(names(t), split = "_")))[,2:1]] <-
      s[t(do.call(cbind, strsplit(names(t), split = "_")))[,2:1]] + t
s
#>    A  B  C  D  E
#> A  1 16 12 22 23
#> B 16  7 21 24 25
#> C 12 21 13 26 27
#> D 22 24 26 19 29
#> E 23 25 27 29 25

答案 1 :(得分:2)

使用outer创建行/列和列/行索引,然后覆盖s的相应值:

sel1 <- match(names(t), outer(rownames(s),colnames(s), function(x,y) paste(x,y,sep="_")))
sel2 <- match(names(t), outer(rownames(s),colnames(s), function(x,y) paste(y,x,sep="_")))
s[sel1] <- s[sel1]+t
s[sel2] <- s[sel2]+t

#   A  B  C  D  E
#A  1 16 12 22 23
#B 16  7 21 24 25
#C 12 21 13 26 27
#D 22 24 26 19 29
#E 23 25 27 29 25

答案 2 :(得分:1)

错误:将修复:您可以使用矩阵索引与行和列的字符值的两列矩阵:

nt <- strsplit(names(t), "_")
dnt <- data.frame(n=t, t(data.frame(nt)))
s[ as.matrix(dnt[-1]) ] <- s[ as.matrix(dnt[-1]) ] + t
s
#-----------
   A  B  C  D  E
A  1 16 11 16 21
B  6  7 12 17 22
C 12 21 13 18 23
D 22 24 26 19 24
E 23 25 27 29 25
 s[as.matrix(dnt[c(3,2)])] <- s[as.matrix(dnt[c(3,2)])] + t
s
#----------
   A  B  C  D  E
A  1 16 13 28 25
B 26  7 30 31 28
C 12 21 13 34 31
D 22 24 26 19 34
E 23 25 27 29 25

答案 3 :(得分:0)

t1 <- as.list(t)
p <- for(i in 1 :length(t1))
{
  nam <-unlist(strsplit(names(t1[i]),"_"))
  s[nam[1],nam[2]]<- t[[i]]
  s[nam[2],nam[1]]<- t[[i]]
}

> s
   A  B  C  D  E
A  1 10  1  6  2
B 10  7  9  7  3
C  1  9 13  8  4
D  6  7  8 19  5
E  2  3  4  5 25