我有一个对称矩阵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;],类似地添加所有其他非对角线元素。对角线什么都不做。
实现这一目标的优雅方式是什么?
答案 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