[R] Stacking matrix columns

@vi@e@gross m@iii@g oii gm@ii@com @vi@e@gross m@iii@g oii gm@ii@com
Mon Aug 7 07:28:07 CEST 2023


This topic is getting almost funny as there are an indefinite ever-sillier
set of ways to perform the action and even more if you include packages like
purr.

If mymat is a matrix, several variants work such as:

> mymat
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> unlist(as.list(mymat))
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
  1   2   3   4   5   6   7   8   9  10  11  12 
> as.vector(unlist(as.data.frame(mymat)))
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

But as noted repeatedly, since underneath it all, mymat is a vector with a
dim attribute, the trivial solution is to set that to NULL or make it 1-D so
the internal algorithm works.

Still, if brute force programming as is done in earlier languages is
important to someone, and you do not want to do it in a language like C,
this would work too.


You could use a for loop in a brute force approach. Here is an example of a
function that I think does what you want and accepts not just matrices (2D
only, no arrays) of any kind but also data.frame or tibble objects as well
as row or column vectors..

mat2vec <- function(mat) {
  # Accept a matrix of any type and return it as
  # a vector stacked by columns.
  
  # Do it the dumb way for illustration.
  
  # If fed a data.frame or tibble, convert it to a matrix first.
  # And handle row or column vectors
  if (is.data.frame(mat)) mat <- as.matrix(mat)
  if (is.vector(mat)) mat <- as.matrix(mat)
  
  # Calculate the rows and columns and the typeof
  # to initialize a vector to hold the result.
  rows <- dim(mat)[1L]
  cols <- dim(mat)[2L]
  type <- typeof(mat)
  result <- vector(length=rows*cols, mode=type)
  
  index <- 1
  
  # Double loop to laboriously copy the items to the result
  
  for (col in 1:cols) {
    for (row in 1:rows) {
      result[index] <- mat[row, col]
      index <- index + 1
    } # end inner loop on rows
  } # end outer loop on cols
  
  return (result)
} # end function daffynition mat2vec

Checking if it works on many cases:

> mymat
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> mat2vec(mymat)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

> mydf
  V1 V2 V3 V4
1  1  4  7 10
2  2  5  8 11
3  3  6  9 12
> mat2vec(mydf)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

> mytib
# A tibble: 3 × 4
     V1    V2    V3    V4
  <int> <int> <int> <int>
1     1     4     7    10
2     2     5     8    11
3     3     6     9    12
> mat2vec(mytib)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

> myboolmat <- mymat <= 5
> myboolmat
     [,1]  [,2]  [,3]  [,4]
[1,] TRUE  TRUE FALSE FALSE
[2,] TRUE  TRUE FALSE FALSE
[3,] TRUE FALSE FALSE FALSE
> mat2vec(myboolmat)
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

> mypi <- pi * mymat
> mat2vec(mypi)
 [1]  3.141593  6.283185  9.424778 12.566371 15.707963 18.849556 21.991149
25.132741 28.274334 31.415927
[11] 34.557519 37.699112

> myletters
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
[1,] "A"  "E"  "I"  "M"  "Q"  "U"  "Y"  "c"  "g"  "k"   "o"   "s"   "w"  
[2,] "B"  "F"  "J"  "N"  "R"  "V"  "Z"  "d"  "h"  "l"   "p"   "t"   "x"  
[3,] "C"  "G"  "K"  "O"  "S"  "W"  "a"  "e"  "i"  "m"   "q"   "u"   "y"  
[4,] "D"  "H"  "L"  "P"  "T"  "X"  "b"  "f"  "j"  "n"   "r"   "v"   "z"  
> mat2vec(myletters)
 [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R"
"S" "T" "U" "V" "W" "X" "Y" "Z" "a"
[28] "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
"t" "u" "v" "w" "x" "y" "z"

> myNA <- matrix(c(NA, Inf, 0), 4, 6)
> myNA
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   NA  Inf    0   NA  Inf    0
[2,]  Inf    0   NA  Inf    0   NA
[3,]    0   NA  Inf    0   NA  Inf
[4,]   NA  Inf    0   NA  Inf    0
> mat2vec(myNA)
 [1]  NA Inf   0  NA Inf   0  NA Inf   0  NA Inf   0  NA Inf   0
[16]  NA Inf   0  NA Inf   0  NA Inf   0

> myvec <- 1:8
> mat2vec(myvec)
[1] 1 2 3 4 5 6 7 8
> mat2vec(t(myvec))
[1] 1 2 3 4 5 6 7 8

> mylist <- list("lions", "tigers", "bears")
> mylist
[[1]]
[1] "lions"

[[2]]
[1] "tigers"

[[3]]
[1] "bears"

> mat2vec(mylist)
[1] "lions"  "tigers" "bears" 

> myohmy <- list("lions", 1, "tigers", 2, "bears", 3, list("oh", "my"))
> myohmy
[[1]]
[1] "lions"

[[2]]
[1] 1

[[3]]
[1] "tigers"

[[4]]
[1] 2

[[5]]
[1] "bears"

[[6]]
[1] 3

[[7]]
[[7]][[1]]
[1] "oh"

[[7]][[2]]
[1] "my"

> mat2vec(myohmy)
[1] "lions"  "1"      "tigers" "2"      "bears"  "3"      "oh"     "my"

Is it bulletproof? Nope. I could make sure it is not any other type or not a
type that cannot be coerced into something like a matrix, or perhaps is of
higher dimensionality.

But as noted, if you already have a valid matrix object, there is a trivial
way to get it by row.


-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of Ebert,Timothy Aaron
Sent: Sunday, August 6, 2023 11:06 PM
To: Rui Barradas <ruipbarradas using sapo.pt>; Iris Simmons <ikwsimmo using gmail.com>;
Steven Yen <styen using ntu.edu.tw>
Cc: R-help Mailing List <r-help using r-project.org>
Subject: Re: [R] Stacking matrix columns



-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of Rui Barradas
Sent: Sunday, August 6, 2023 7:37 PM
To: Iris Simmons <ikwsimmo using gmail.com>; Steven Yen <styen using ntu.edu.tw>
Cc: R-help Mailing List <r-help using r-project.org>
Subject: Re: [R] Stacking matrix columns

[External Email]

Às 01:15 de 06/08/2023, Iris Simmons escreveu:
> You could also do
>
> dim(x) <- c(length(x), 1)
>
> On Sat, Aug 5, 2023, 20:12 Steven Yen <styen using ntu.edu.tw> wrote:
>
>> I wish to stack columns of a matrix into one column. The following
>> matrix command does it. Any other ways? Thanks.
>>
>>   > x<-matrix(1:20,5,4)
>>   > x
>>        [,1] [,2] [,3] [,4]
>> [1,]    1    6   11   16
>> [2,]    2    7   12   17
>> [3,]    3    8   13   18
>> [4,]    4    9   14   19
>> [5,]    5   10   15   20
>>
>>   > matrix(x,ncol=1)
>>         [,1]
>>    [1,]    1
>>    [2,]    2
>>    [3,]    3
>>    [4,]    4
>>    [5,]    5
>>    [6,]    6
>>    [7,]    7
>>    [8,]    8
>>    [9,]    9
>> [10,]   10
>> [11,]   11
>> [12,]   12
>> [13,]   13
>> [14,]   14
>> [15,]   15
>> [16,]   16
>> [17,]   17
>> [18,]   18
>> [19,]   19
>> [20,]   20
>>   >
>>
>> ______________________________________________
>> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> https://sta/
>> t.ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7Ctebert%40ufl.e
>> du%7C0777cc9a4f7b4d06730008db96d60c04%7C0d4da0f84a314d76ace60a62331e1
>> b84%7C0%7C0%7C638269618308876684%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
>> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7
>> C&sdata=SuBbb9Zv2Zodb1p2Urk4a8yl%2FsGNfxUDxB7MqFlaTZc%3D&reserved=0
>> PLEASE do read the posting guide
>> http://www/.
>> r-project.org%2Fposting-guide.html&data=05%7C01%7Ctebert%40ufl.edu%7C
>> 0777cc9a4f7b4d06730008db96d60c04%7C0d4da0f84a314d76ace60a62331e1b84%7
>> C0%7C0%7C638269618308876684%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwM
>> DAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sda
>> ta=usT0%2FPcAyZZsp7IorVV31xXBqlMvH6tO3758UmKja44%3D&reserved=0
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
>       [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat/
> .ethz.ch%2Fmailman%2Flistinfo%2Fr-help&data=05%7C01%7Ctebert%40ufl.edu
> %7C0777cc9a4f7b4d06730008db96d60c04%7C0d4da0f84a314d76ace60a62331e1b84
> %7C0%7C0%7C638269618308876684%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sda
> ta=SuBbb9Zv2Zodb1p2Urk4a8yl%2FsGNfxUDxB7MqFlaTZc%3D&reserved=0
> PLEASE do read the posting guide
> http://www.r/
> -project.org%2Fposting-guide.html&data=05%7C01%7Ctebert%40ufl.edu%7C07
> 77cc9a4f7b4d06730008db96d60c04%7C0d4da0f84a314d76ace60a62331e1b84%7C0%
> 7C0%7C638269618308876684%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiL
> CJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=us
> T0%2FPcAyZZsp7IorVV31xXBqlMvH6tO3758UmKja44%3D&reserved=0
> and provide commented, minimal, self-contained, reproducible code.
Hello,

Yet another solution.


t(t(c(x)))

or

x |> c() |> t() |> t()


At first I liked it but it's the slowest of the three, OP's, Iris' (the
fastest).

Hope this helps,

Rui Barradas

______________________________________________
R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.r-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

______________________________________________
R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list