行列またはデータフレームを拡張して、同じ行名と列名を持つ2次式にします

Aug 21 2020

行列またはデータフレームを簡単に拡張して2次式にする、つまり同じ行名と列名を使用するにはどうすればよいですか。値が欠落している場合は、ゼロにしたいだけです。

再現可能な例:

cols<-c("A","B","D","F")
rows<-c("A","B","C", "E", "F")
data<-matrix(runif(20),nrow = length(rows), ncol = length(cols))
colnames(data)<-cols
rownames(data)<-rows

したがって、目標は、列/行名が「A」から「F」で、データと同じ値で、欠落している場合はゼロで埋められた6x6の行列を作成することです。

アイデアをありがとう!

回答

2 AllanCameron Aug 21 2020 at 21:02

これは少し時間がかかるように見えますが、行名と列名を持つ任意の行列に一般化する小さな関数を次に示します。

make_quadratic <- function(data)
{
  names <- sort(unique(c(colnames(data), rownames(data))))
  size  <- length(names)
  
 `colnames<-`(`rownames<-`(apply(apply(data, 1, 
  function(x) replace(numeric(size), names %in% colnames(data), x)), 1, 
  function(x) replace(numeric(size), names %in% rownames(data), x)),
  names), names)
}

したがって、たとえば:

make_quadratic(data)
#>           A         B C         D E          F
#> A 0.1033626 0.4390343 0 0.9368352 0 0.47888726
#> B 0.3897981 0.1563756 0 0.3148652 0 0.79636682
#> C 0.6780338 0.4937433 0 0.1325104 0 0.10266721
#> D 0.0000000 0.0000000 0 0.0000000 0 0.00000000
#> E 0.7667374 0.1198529 0 0.8930371 0 0.35349412
#> F 0.1467854 0.4649394 0 0.5838215 0 0.05615008

編集

ループを含まない別の答え:

i <- as.matrix(expand.grid(row = which(LETTERS[1:6] %in% rownames(data)),
                           col = which(LETTERS[1:6] %in% colnames(data))))

result <- matrix(0, nrow = 6, ncol = 6, 
                 dimnames = list(LETTERS[1:6], LETTERS[1:6]))

result[i] <- data

result
#>           A         B C         D E          F
#> A 0.1033626 0.4390343 0 0.9368352 0 0.47888726
#> B 0.3897981 0.1563756 0 0.3148652 0 0.79636682
#> C 0.6780338 0.4937433 0 0.1325104 0 0.10266721
#> D 0.0000000 0.0000000 0 0.0000000 0 0.00000000
#> E 0.7667374 0.1198529 0 0.8930371 0 0.35349412
#> F 0.1467854 0.4649394 0 0.5838215 0 0.05615008
2 ThomasIsCoding Aug 21 2020 at 21:19

ネストされたforループを使用する別のベースRオプションは次のとおりです

nm <- sort(union(colnames(data),row.names(data)))
res <- `dimnames<-`(matrix(0,nrow = length(nm),ncol = length(nm)),replicate(2,nm,simplify = FALSE))
for (i in rows) {
  for (j in cols) {
    res[i,j] <- data[i,j]
  }
}

これは

> res
           A         B C         D E          F
A 0.02778712 0.1386282 0 0.2263808 0 0.68144251
B 0.52731078 0.3214921 0 0.1314165 0 0.09916910
C 0.88031907 0.1548316 0 0.9815635 0 0.11890256
D 0.00000000 0.0000000 0 0.0000000 0 0.00000000
E 0.37306337 0.1322282 0 0.3270137 0 0.05043966
F 0.04795913 0.2213059 0 0.5069395 0 0.92925392