[R] Transfer a 3-dimensional array to a matrix in R

Dénes Tóth toth.denes at ttk.mta.hu
Tue Oct 20 21:03:20 CEST 2015


Hi,

Bill was faster than me in suggesting aperm() instead of apply(), 
however, his solution is still suboptimal. Try to avoid array(), and
set the dimensions directly if possible.

----

fn1 <- function(x) {
     apply(x, 3, t)
}


fn2 <- function(x) {
     array(aperm(x, c(2, 1, 3)), c(prod(dim(x)[1:2]), dim(x)[3]))
}

fn3 <- function(x) {
     x <- aperm(x, c(2, 1, 3))
     dim(x) <- c(prod(dim(x)[1:2]), dim(x)[3])
     x
}

# check that the functions return the same
x <- array(1:18, dim=c(3, 2, 3))
stopifnot(identical(fn1(x), fn2(x)))
stopifnot(identical(fn1(x), fn3(x)))

# create two larger arrays, play with the size of the 3rd dimension
x <- array(1:18e4, dim=c(3, 2e1, 3e3))
y <- array(1:18e4, dim=c(3e3, 2e1, 3))

# and the timing:
library(microbenchmark)
microbenchmark(fn1(x), fn2(x), fn3(x), fn1(y), fn2(y), fn3(y), times = 100L)

---

Conclusion:
fn3() is about 3x as fast as fn2(), and fn1() can be extremely 
inefficient if dim(x)[3] is large.


HTH,
   Denes




On 10/20/2015 08:48 PM, William Dunlap wrote:
> Or use aperm() (array index permuation):
>    > array(aperm(x, c(2,1,3)), c(6,3))
>         [,1] [,2] [,3]
>    [1,]    1    7   13
>    [2,]    4   10   16
>    [3,]    2    8   14
>    [4,]    5   11   17
>    [5,]    3    9   15
>    [6,]    6   12   18
>
> Bill Dunlap
> TIBCO Software
> wdunlap tibco.com
>
>
> On Tue, Oct 20, 2015 at 11:31 AM, John Laing <john.laing at gmail.com> wrote:
>>> x <- array(1:18, dim=c(3, 2, 3))
>>> x
>> , , 1
>>
>>       [,1] [,2]
>> [1,]    1    4
>> [2,]    2    5
>> [3,]    3    6
>>
>> , , 2
>>
>>       [,1] [,2]
>> [1,]    7   10
>> [2,]    8   11
>> [3,]    9   12
>>
>> , , 3
>>
>>       [,1] [,2]
>> [1,]   13   16
>> [2,]   14   17
>> [3,]   15   18
>>
>>> apply(x, 3, t)
>>       [,1] [,2] [,3]
>> [1,]    1    7   13
>> [2,]    4   10   16
>> [3,]    2    8   14
>> [4,]    5   11   17
>> [5,]    3    9   15
>> [6,]    6   12   18
>>
>>
>> On Tue, Oct 20, 2015 at 12:39 PM, Chunyu Dong <dongchunyu2004 at 163.com>
>> wrote:
>>
>>> Hello!
>>>
>>>
>>> Recently I am trying to transfer a large 3-dimensional array to a matrix.
>>> For example, a array like:
>>> , , 1
>>>       [,1] [,2]
>>> [1,]    1    4
>>> [2,]    2    5
>>> [3,]    3    6
>>> , , 2
>>>       [,1] [,2]
>>> [1,]    7   10
>>> [2,]    8   11
>>> [3,]    9   12
>>> , , 3
>>>       [,1] [,2]
>>> [1,]   13   16
>>> [2,]   14   17
>>> [3,]   15   18
>>>
>>>
>>> I would like to transfer it to a matrix like:
>>> 1        7          13
>>> 4        10        16
>>> 2        8          14
>>> 5        11        17
>>> 3        9          15
>>> 6        12        18
>>>
>>>
>>> Could you tell me how to do it in R ? Thank you very much!
>>>
>>>
>>> Best regards,
>>> Chunyu
>>>
>>>
>>>
>>>
>>>
>>>          [[alternative HTML version deleted]]
>>>
>>> ______________________________________________
>>> R-help at 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.
>>>
>>
>>          [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> R-help at 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 at 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