私は次の行列'x'を持っています
a b
a 1 3
b 2 4
これは非常に大きなマトリックスです(この質問のためにトリミングされています)。このマトリックスを、行名と列名の組み合わせごとに、そのセルの値とともに出力したいと思います。したがって、期待される出力は次のようになります。
a,a,1
a,b,3
b,a,2
b,b,4
それらをループすることはできますが、これは回避できると確信しています(適用しますか?)。どんなポインタでも大歓迎です。
1つの方法は、パッケージのmelt
関数を使用することです。reshape2
x <- matrix(1:4, nrow = 2, ncol = 2,
dimnames = list(dim1 = c("a", "b"), dim2 = c("a", "b")))
library(reshape2)
melt(x)
# dim1 dim2 value
# 1 a a 1
# 2 b a 2
# 3 a b 3
# 4 b b 4
編集 データが大きすぎて速度が問題になる場合は、次のこともお勧めします。
data.frame(dim1 = rep(rownames(x), ncol(x)),
dim2 = rep(colnames(x), each = nrow(x)),
value = c(x))
Edit2
比較的ビッグデータでテストした後、私は除外しませんmelt
:
x <- matrix(runif(9e6), nrow = 3000, ncol = 3000,
dimnames = list(dim1 = paste0("x", runif(3000)),
dim2 = paste0("y", runif(3000))))
system.time(y1 <- melt(x))
# user system elapsed
# 1.17 0.44 1.61
system.time(y2 <- data.frame(dim1 = rep(rownames(x), ncol(x)),
dim2 = rep(colnames(x), each = nrow(x)),
value = c(x)))
# user system elapsed
# 1.98 0.37 2.36
ベース R 関数row
を 使用することもできます。col
を参照したい場合はrow.names
、col.names
を使用しますas.factor = T
。行列を使用as.character
してas.numeric
平坦化します。
do.call(data.frame,list(lapply(list(row = row(x, T),col=col(x,T)), as.character),
value =as.numeric(x)))
## row col value
## 1 a a 1
## 2 b a 2
## 3 a b 3
## 4 b b 4
が必要な場合matrix
は、すべての列を同じクラスとして持つ必要があります (character
またはnumeric
。その後、使用できます
do.call(cbind, lapply(list(row = row(x), col = col(x), value = x), as.numeric))
## row col value
## [1,] 1 1 1
## [2,] 2 1 2
## [3,] 1 2 3
## [4,] 2 2 4
もしくはキャラとして
do.call(cbind, lapply(list(row = row(x, T), col = col(x, T), value = x), as.character))
## row col value
## [1,] "a" "a" "1"
## [2,] "b" "a" "2"
## [3,] "a" "b" "3"
## [4,] "b" "b" "4"