1000 x 1000の大きな2Dマトリックスがあります。これを1列(または行)になるように変形したいと思います。たとえば、マトリックスが次の場合:
A B C
1 4 7
2 5 8
3 6 9
私はそれを有効にしたい:
1 2 3 4 5 6 7 8 9
列ヘッダーを保持する必要はなく、データの順序だけを保持する必要があります。 reshape2
(これが最も使いやすいと推定したパッケージ)を使用してこれを行うにはどうすればよいですか?
明確にするために、reshape
に言及しました。これが最善の方法だと思いました。私は完全に満足している簡単な方法があることがわかります。
よりコンパクトな方法を見つけるのは難しいと思います:
c(m)
[1] 1 2 3 4 5 6 7 8 9
ただし、マトリックス構造を保持する場合は、このdim属性の修正が効果的です。
dim(m) <- c(dim(m)[1]*dim(m)[2], 1)
m
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
[9,] 9
次元の積を取得するよりコンパクトな方法がありますが、上記の方法は、dim属性が行列の2要素ベクトルであることを強調しています。その例で「9」を取得する他の方法は次のとおりです。
> prod(dim(m))
[1] 9
> length(m)
[1] 9
可能な解決策ですが、reshape2を使用しません。
> m <- matrix(c(1:9), ncol = 3)
> m
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> as.vector(m)
[1] 1 2 3 4 5 6 7 8 9
Rの皆さん、OPにreshape2ソリューションを提供しましょう:
> m <- matrix(c(1:9), ncol = 3)
> melt(m)$value
[1] 1 2 3 4 5 6 7 8 9
私はそれがc(m)よりもどれだけ遅いかをテストするだけでは困りません。ただし、同じです:
> identical(c(m),melt(m)$value)
[1] TRUE
[編集:冗談だろ
> system.time(for(i in 1:1000){z=melt(m)$value})
user system elapsed
1.653 0.004 1.662
> system.time(for(i in 1:1000){z=c(m)})
user system elapsed
0.004 0.000 0.004
as.vector(m)はc(m)より少し効率的です:
> library(rbenchmark)
> m <- diag(5000)
> benchmark(
+ vect = as.vector(m),
+ conc = c(m),
+ replications=100
+ )
test replications elapsed relative user.self sys.self user.child sys.child
2 conc 100 12.699 1.177 6.952 5.754 0 0
1 vect 100 10.785 1.000 4.858 5.933 0 0
関数「sapply」を使用してそれを行うもう1つの簡単な方法(または、「for」ループでも同じことができます)
m <- matrix(c(1:9), ncol = 3)
(m1 <- as.numeric(sapply(1:NROW(m), function(i)(m[,i]))))