Reputation: 2763
I have the following matrix:
m <- matrix(1:9, ncol=3, byrow=TRUE)
m
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
that I need to flatten, i.e., convert to a vector.
However, instead of going along the columns:
as.vector(m)
[1] 7 4 1 8 5 2 9 6 3
I need the resulting vector to go along the rows and from the bottom and to the right, e.g.:
[1] 7 8 9 4 5 6 1 2 3
How can I do that?
Upvotes: 3
Views: 857
Reputation: 269852
1) Reverse the first dimension, tranpose and then unravel:
c(t(m[nrow(m):1, ]))
## [1] 7 8 9 4 5 6 1 2 3
2) Here is a second approach which computes the indices and then applies them. It is longer but avoids the transpose:
nr <- nrow(m)
nc <- ncol(m)
c(m[cbind(rep(nr:1, each = nc), 1:nc)])
## [1] 7 8 9 4 5 6 1 2 3
2a) A variation of (2) is to use a 1d index:
m[rep(nr:1, each = nc) + nr * (0:(nc - 1))]
## [1] 7 8 9 4 5 6 1 2 3
I tried it for a 100x100 and a 1000x1000 matrix. In the first case (1) was the fastest and in the second case (2) and (2a) were the fastest thus if speed is a concern the actual dimensions seem to make a difference as to which to choose.
Upvotes: 6
Reputation: 40091
One option could be also using asplit()
:
unlist(rev(asplit(m, 1)))
[1] 7 8 9 4 5 6 1 2 3
Upvotes: 1
Reputation: 102241
Maybe you can use the following ways:
Solution 1:
as.vector(t(apply(m, 2, rev)))
which gives:
> as.vector(t(apply(m, 2, rev)))
[1] 7 8 9 4 5 6 1 2 3
Solution 2:
unlist(rev(data.frame(t(m))),use.names = F)
which gives:
> unlist(rev(data.frame(t(m))),use.names = F)
[1] 7 8 9 4 5 6 1 2 3
Upvotes: 0