Generalized permutation of the dimensions of an array
aperm2.Rd
aperm2()
extends the functionality of
base::aperm()
by allowing dropping and/or
adding ineffective dimensions (i.e. dimensions with an extent of 1)
from/to the input array, in addition to permuting its dimensions.
Note that, like base::aperm()
, aperm2()
always preserves the length of the input array. However, unlike with
base::aperm()
, the array returned by aperm2()
doesn't necessarily have the same number of dimensions as the input array.
Arguments
- a
An ordinary array.
- perm
An integer vector, possibly containing
NA
s, indicating how the dimensions of the returned array should be mapped to those of the input array.More precisely,
perm
can be one of the following:A permutation of the
seq_along(dim(a))
vector, like forbase::aperm()
. Note that if the identity permutation is used (i.e.perm=seq_along(dim(a))
), thenaperm2()
is a no-op (like withbase::aperm()
).A permutation of a subset of the
seq_along(dim(a))
vector. In this case the dimensions that are excluded must be ineffective dimensions i.e. each of them must have an extent of 1. In other words, only integers that belong towhich(dim(a) == 1)
can be missing fromperm
.In this case, the ineffective dimensions that are excluded will be dropped i.e. they won't be carried over to the returned array.
Additionally, any number of
NA
s can be inserted anywhere in aperm
vector like one described above.In this case, ineffective dimensions will be added to the returned array. These added dimensions will materialize as additional
1
's in thedim()
vector of the returned array, at positions that match the positions of theNA
s inperm
.
Note that if
perm
is missing, thenaperm2(a)
reverses the order ofa
's dimensions (i.e.perm
gets set torev(seq_along(dim(a)))
), likebase::aperm(a)
does.
Value
An array with one dimension per element in the perm
argument.
The length of the returned array will always be the same as the length
of the input array. (Note that for an array a
, length(a)
is prod(dim(a))
.)
Note
The aperm()
method for DelayedArray objects
defined in the DelayedArray package implements the "aperm2
semantic", that is, it allows dropping and/or adding ineffective
dimensions from/to the input DelayedArray object.
See also
aperm
in the base package for the function thataperm2
is based on.aperm
in the BiocGenerics package for theaperm
S4 generic function.aperm,SVT_SparseArray-method in the SparseArray package and aperm,DelayedArray-method in the DelayedArray package for
aperm()
methods that implements the "aperm2
semantic".
Examples
## ---------------------------------------------------------------------
## SOME EXAMPLES WITH A 4D ARRAY
## ---------------------------------------------------------------------
a <- array(1:72, c(3, 6, 1, 4),
dimnames=list(NULL, letters[1:6], NULL, LETTERS[1:4]))
a
#> , , 1, A
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , 1, B
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , 1, C
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , 1, D
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
## Permute first two dimensions:
aperm2(a, perm=c(2,1,3,4))
#> , , 1, A
#>
#> [,1] [,2] [,3]
#> a 1 2 3
#> b 4 5 6
#> c 7 8 9
#> d 10 11 12
#> e 13 14 15
#> f 16 17 18
#>
#> , , 1, B
#>
#> [,1] [,2] [,3]
#> a 19 20 21
#> b 22 23 24
#> c 25 26 27
#> d 28 29 30
#> e 31 32 33
#> f 34 35 36
#>
#> , , 1, C
#>
#> [,1] [,2] [,3]
#> a 37 38 39
#> b 40 41 42
#> c 43 44 45
#> d 46 47 48
#> e 49 50 51
#> f 52 53 54
#>
#> , , 1, D
#>
#> [,1] [,2] [,3]
#> a 55 56 57
#> b 58 59 60
#> c 61 62 63
#> d 64 65 66
#> e 67 68 69
#> f 70 71 72
#>
## Permute first and last dimensions:
aperm2(a, perm=c(4,2,3,1))
#> , , 1, 1
#>
#> a b c d e f
#> A 1 4 7 10 13 16
#> B 19 22 25 28 31 34
#> C 37 40 43 46 49 52
#> D 55 58 61 64 67 70
#>
#> , , 1, 2
#>
#> a b c d e f
#> A 2 5 8 11 14 17
#> B 20 23 26 29 32 35
#> C 38 41 44 47 50 53
#> D 56 59 62 65 68 71
#>
#> , , 1, 3
#>
#> a b c d e f
#> A 3 6 9 12 15 18
#> B 21 24 27 30 33 36
#> C 39 42 45 48 51 54
#> D 57 60 63 66 69 72
#>
## Drop 3rd dimension:
aperm2(a, perm=c(1,2,4))
#> , , A
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , B
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , C
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , D
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
## Drop 3rd dimension and permute 2nd and last:
aperm2(a, perm=c(1,4,2))
#> , , a
#>
#> A B C D
#> [1,] 1 19 37 55
#> [2,] 2 20 38 56
#> [3,] 3 21 39 57
#>
#> , , b
#>
#> A B C D
#> [1,] 4 22 40 58
#> [2,] 5 23 41 59
#> [3,] 6 24 42 60
#>
#> , , c
#>
#> A B C D
#> [1,] 7 25 43 61
#> [2,] 8 26 44 62
#> [3,] 9 27 45 63
#>
#> , , d
#>
#> A B C D
#> [1,] 10 28 46 64
#> [2,] 11 29 47 65
#> [3,] 12 30 48 66
#>
#> , , e
#>
#> A B C D
#> [1,] 13 31 49 67
#> [2,] 14 32 50 68
#> [3,] 15 33 51 69
#>
#> , , f
#>
#> A B C D
#> [1,] 16 34 52 70
#> [2,] 17 35 53 71
#> [3,] 18 36 54 72
#>
## Drop 3rd dimension and cycle the order of the remaining ones:
aperm2(a, perm=c(2,4,1))
#> , , 1
#>
#> A B C D
#> a 1 19 37 55
#> b 4 22 40 58
#> c 7 25 43 61
#> d 10 28 46 64
#> e 13 31 49 67
#> f 16 34 52 70
#>
#> , , 2
#>
#> A B C D
#> a 2 20 38 56
#> b 5 23 41 59
#> c 8 26 44 62
#> d 11 29 47 65
#> e 14 32 50 68
#> f 17 35 53 71
#>
#> , , 3
#>
#> A B C D
#> a 3 21 39 57
#> b 6 24 42 60
#> c 9 27 45 63
#> d 12 30 48 66
#> e 15 33 51 69
#> f 18 36 54 72
#>
## Add one ineffective dimension:
aperm2(a, perm=c(NA,1,2,3,4))
#> , , a, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#>
#> , , b, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 4 5 6
#>
#> , , c, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 7 8 9
#>
#> , , d, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 10 11 12
#>
#> , , e, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 13 14 15
#>
#> , , f, 1, A
#>
#> [,1] [,2] [,3]
#> [1,] 16 17 18
#>
#> , , a, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 19 20 21
#>
#> , , b, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 22 23 24
#>
#> , , c, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 25 26 27
#>
#> , , d, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 28 29 30
#>
#> , , e, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 31 32 33
#>
#> , , f, 1, B
#>
#> [,1] [,2] [,3]
#> [1,] 34 35 36
#>
#> , , a, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 37 38 39
#>
#> , , b, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 40 41 42
#>
#> , , c, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 43 44 45
#>
#> , , d, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 46 47 48
#>
#> , , e, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 49 50 51
#>
#> , , f, 1, C
#>
#> [,1] [,2] [,3]
#> [1,] 52 53 54
#>
#> , , a, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 55 56 57
#>
#> , , b, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 58 59 60
#>
#> , , c, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 61 62 63
#>
#> , , d, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 64 65 66
#>
#> , , e, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 67 68 69
#>
#> , , f, 1, D
#>
#> [,1] [,2] [,3]
#> [1,] 70 71 72
#>
aperm2(a, perm=c(1,NA,2,3,4))
#> , , a, 1, A
#>
#> [,1]
#> [1,] 1
#> [2,] 2
#> [3,] 3
#>
#> , , b, 1, A
#>
#> [,1]
#> [1,] 4
#> [2,] 5
#> [3,] 6
#>
#> , , c, 1, A
#>
#> [,1]
#> [1,] 7
#> [2,] 8
#> [3,] 9
#>
#> , , d, 1, A
#>
#> [,1]
#> [1,] 10
#> [2,] 11
#> [3,] 12
#>
#> , , e, 1, A
#>
#> [,1]
#> [1,] 13
#> [2,] 14
#> [3,] 15
#>
#> , , f, 1, A
#>
#> [,1]
#> [1,] 16
#> [2,] 17
#> [3,] 18
#>
#> , , a, 1, B
#>
#> [,1]
#> [1,] 19
#> [2,] 20
#> [3,] 21
#>
#> , , b, 1, B
#>
#> [,1]
#> [1,] 22
#> [2,] 23
#> [3,] 24
#>
#> , , c, 1, B
#>
#> [,1]
#> [1,] 25
#> [2,] 26
#> [3,] 27
#>
#> , , d, 1, B
#>
#> [,1]
#> [1,] 28
#> [2,] 29
#> [3,] 30
#>
#> , , e, 1, B
#>
#> [,1]
#> [1,] 31
#> [2,] 32
#> [3,] 33
#>
#> , , f, 1, B
#>
#> [,1]
#> [1,] 34
#> [2,] 35
#> [3,] 36
#>
#> , , a, 1, C
#>
#> [,1]
#> [1,] 37
#> [2,] 38
#> [3,] 39
#>
#> , , b, 1, C
#>
#> [,1]
#> [1,] 40
#> [2,] 41
#> [3,] 42
#>
#> , , c, 1, C
#>
#> [,1]
#> [1,] 43
#> [2,] 44
#> [3,] 45
#>
#> , , d, 1, C
#>
#> [,1]
#> [1,] 46
#> [2,] 47
#> [3,] 48
#>
#> , , e, 1, C
#>
#> [,1]
#> [1,] 49
#> [2,] 50
#> [3,] 51
#>
#> , , f, 1, C
#>
#> [,1]
#> [1,] 52
#> [2,] 53
#> [3,] 54
#>
#> , , a, 1, D
#>
#> [,1]
#> [1,] 55
#> [2,] 56
#> [3,] 57
#>
#> , , b, 1, D
#>
#> [,1]
#> [1,] 58
#> [2,] 59
#> [3,] 60
#>
#> , , c, 1, D
#>
#> [,1]
#> [1,] 61
#> [2,] 62
#> [3,] 63
#>
#> , , d, 1, D
#>
#> [,1]
#> [1,] 64
#> [2,] 65
#> [3,] 66
#>
#> , , e, 1, D
#>
#> [,1]
#> [1,] 67
#> [2,] 68
#> [3,] 69
#>
#> , , f, 1, D
#>
#> [,1]
#> [1,] 70
#> [2,] 71
#> [3,] 72
#>
aperm2(a, perm=c(1,2,NA,3,4))
#> , , 1, 1, A
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , 1, 1, B
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , 1, 1, C
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , 1, 1, D
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
aperm2(a, perm=c(1,2,3,NA,4))
#> , , 1, 1, A
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , 1, 1, B
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , 1, 1, C
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , 1, 1, D
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
aperm2(a, perm=c(1,2,3,4,NA))
#> , , 1, A, 1
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , 1, B, 1
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , 1, C, 1
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , 1, D, 1
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
## Add four ineffective dimensions:
aperm2(a, perm=c(NA,1,2,3,NA,NA,4,NA))
#> , , a, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#>
#> , , b, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 4 5 6
#>
#> , , c, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 7 8 9
#>
#> , , d, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 10 11 12
#>
#> , , e, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 13 14 15
#>
#> , , f, 1, 1, 1, A, 1
#>
#> [,1] [,2] [,3]
#> [1,] 16 17 18
#>
#> , , a, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 19 20 21
#>
#> , , b, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 22 23 24
#>
#> , , c, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 25 26 27
#>
#> , , d, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 28 29 30
#>
#> , , e, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 31 32 33
#>
#> , , f, 1, 1, 1, B, 1
#>
#> [,1] [,2] [,3]
#> [1,] 34 35 36
#>
#> , , a, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 37 38 39
#>
#> , , b, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 40 41 42
#>
#> , , c, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 43 44 45
#>
#> , , d, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 46 47 48
#>
#> , , e, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 49 50 51
#>
#> , , f, 1, 1, 1, C, 1
#>
#> [,1] [,2] [,3]
#> [1,] 52 53 54
#>
#> , , a, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 55 56 57
#>
#> , , b, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 58 59 60
#>
#> , , c, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 61 62 63
#>
#> , , d, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 64 65 66
#>
#> , , e, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 67 68 69
#>
#> , , f, 1, 1, 1, D, 1
#>
#> [,1] [,2] [,3]
#> [1,] 70 71 72
#>
## Permute first and last dimensions and add one ineffective dimension:
aperm2(a, perm=c(4,2,3,NA,1))
#> , , 1, 1, 1
#>
#> a b c d e f
#> A 1 4 7 10 13 16
#> B 19 22 25 28 31 34
#> C 37 40 43 46 49 52
#> D 55 58 61 64 67 70
#>
#> , , 1, 1, 2
#>
#> a b c d e f
#> A 2 5 8 11 14 17
#> B 20 23 26 29 32 35
#> C 38 41 44 47 50 53
#> D 56 59 62 65 68 71
#>
#> , , 1, 1, 3
#>
#> a b c d e f
#> A 3 6 9 12 15 18
#> B 21 24 27 30 33 36
#> C 39 42 45 48 51 54
#> D 57 60 63 66 69 72
#>
## Drop 3rd dimension, cycle the order of the remaining ones, and add
## two ineffective dimensions:
aperm2(a, perm=c(2,4,NA,1,NA))
#> , , 1, 1, 1
#>
#> A B C D
#> a 1 19 37 55
#> b 4 22 40 58
#> c 7 25 43 61
#> d 10 28 46 64
#> e 13 31 49 67
#> f 16 34 52 70
#>
#> , , 1, 2, 1
#>
#> A B C D
#> a 2 20 38 56
#> b 5 23 41 59
#> c 8 26 44 62
#> d 11 29 47 65
#> e 14 32 50 68
#> f 17 35 53 71
#>
#> , , 1, 3, 1
#>
#> A B C D
#> a 3 21 39 57
#> b 6 24 42 60
#> c 9 27 45 63
#> d 12 30 48 66
#> e 15 33 51 69
#> f 18 36 54 72
#>
## No-op:
aperm2(a, perm=seq_along(dim(a)))
#> , , 1, A
#>
#> a b c d e f
#> [1,] 1 4 7 10 13 16
#> [2,] 2 5 8 11 14 17
#> [3,] 3 6 9 12 15 18
#>
#> , , 1, B
#>
#> a b c d e f
#> [1,] 19 22 25 28 31 34
#> [2,] 20 23 26 29 32 35
#> [3,] 21 24 27 30 33 36
#>
#> , , 1, C
#>
#> a b c d e f
#> [1,] 37 40 43 46 49 52
#> [2,] 38 41 44 47 50 53
#> [3,] 39 42 45 48 51 54
#>
#> , , 1, D
#>
#> a b c d e f
#> [1,] 55 58 61 64 67 70
#> [2,] 56 59 62 65 68 71
#> [3,] 57 60 63 66 69 72
#>
## Reverse the order of the dimensions (multidimensional transposition):
aperm2(a) # same as 'aperm2(a, perm=rev(seq_along(dim(a))))'
#> , , a, 1
#>
#> [,1]
#> A 1
#> B 19
#> C 37
#> D 55
#>
#> , , b, 1
#>
#> [,1]
#> A 4
#> B 22
#> C 40
#> D 58
#>
#> , , c, 1
#>
#> [,1]
#> A 7
#> B 25
#> C 43
#> D 61
#>
#> , , d, 1
#>
#> [,1]
#> A 10
#> B 28
#> C 46
#> D 64
#>
#> , , e, 1
#>
#> [,1]
#> A 13
#> B 31
#> C 49
#> D 67
#>
#> , , f, 1
#>
#> [,1]
#> A 16
#> B 34
#> C 52
#> D 70
#>
#> , , a, 2
#>
#> [,1]
#> A 2
#> B 20
#> C 38
#> D 56
#>
#> , , b, 2
#>
#> [,1]
#> A 5
#> B 23
#> C 41
#> D 59
#>
#> , , c, 2
#>
#> [,1]
#> A 8
#> B 26
#> C 44
#> D 62
#>
#> , , d, 2
#>
#> [,1]
#> A 11
#> B 29
#> C 47
#> D 65
#>
#> , , e, 2
#>
#> [,1]
#> A 14
#> B 32
#> C 50
#> D 68
#>
#> , , f, 2
#>
#> [,1]
#> A 17
#> B 35
#> C 53
#> D 71
#>
#> , , a, 3
#>
#> [,1]
#> A 3
#> B 21
#> C 39
#> D 57
#>
#> , , b, 3
#>
#> [,1]
#> A 6
#> B 24
#> C 42
#> D 60
#>
#> , , c, 3
#>
#> [,1]
#> A 9
#> B 27
#> C 45
#> D 63
#>
#> , , d, 3
#>
#> [,1]
#> A 12
#> B 30
#> C 48
#> D 66
#>
#> , , e, 3
#>
#> [,1]
#> A 15
#> B 33
#> C 51
#> D 69
#>
#> , , f, 3
#>
#> [,1]
#> A 18
#> B 36
#> C 54
#> D 72
#>
## ---------------------------------------------------------------------
## COMPOSING aperm2() TRANSFORMATIONS
## ---------------------------------------------------------------------
## Applying two successive aperm() transformations, first with 'perm'
## set to 'perm1' then set to 'perm2', is equivalent to applying a
## single aperm() transformation with 'perm' set to 'perm1[perm2]'.
##
## More formally:
## aperm(aperm(a, perm=perm1), perm=perm2)
## is equivalent to:
## aperm(a, perm=perm1[perm2])
##
## Note that this also applies to aperm2()!
## Examples with aperm():
perm1 <- c(2,4,3,1)
perm2 <- c(4,3,2,1)
perm3 <- c(2,1,4,3)
a12 <- aperm(aperm(a, perm=perm1), perm=perm2)
stopifnot(identical(a12, aperm(a, perm=perm1[perm2])))
a13 <- aperm(aperm(a, perm=perm1), perm=perm3)
stopifnot(identical(a13, aperm(a, perm=perm1[perm3])))
a23 <- aperm(aperm(a, perm=perm2), perm=perm3)
stopifnot(identical(a23, aperm(a, perm=perm2[perm3])))
a123 <- aperm(aperm(aperm(a, perm=perm1), perm=perm2), perm=perm3)
stopifnot(identical(a123, aperm(a, perm=perm1[perm2][perm3])))
stopifnot(identical(a123, aperm(a, perm=perm1[perm2[perm3]])))
## Examples with aperm2():
perm1 <- c(2,4,1)
perm2 <- c(1,3,NA,2,NA)
perm3 <- c(5,4,2,1)
a12 <- aperm2(aperm2(a, perm=perm1), perm=perm2)
stopifnot(identical(a12, aperm2(a, perm=perm1[perm2])))
a123 <- aperm2(aperm2(aperm2(a, perm=perm1), perm=perm2), perm=perm3)
stopifnot(identical(a123, aperm2(a, perm=perm1[perm2][perm3])))
stopifnot(identical(a123, aperm2(a, perm=perm1[perm2[perm3]])))
## ---------------------------------------------------------------------
## REVERSIBILITY OF THE aperm2() TRANSFORMATION
## ---------------------------------------------------------------------
## An aperm() or aperm2() transformation is always reversible.
## The 'perm' vector to use to achieve the reverse transformation
## can be inferred from the initial 'perm' vector using the following
## helper function ('n' must be the number of dimensions of
## the original array):
build_rev_perm <- function(perm, n=length(perm)) {
rev_perm <- rep.int(NA_integer_, n)
na_idx <- which(!is.na(perm))
rev_perm[perm[na_idx]] <- na_idx
rev_perm
}
## Examples:
perm <- c(2,4,NA,1,NA)
rev_perm <- build_rev_perm(perm, n=length(dim(a)))
stopifnot(identical(aperm2(aperm2(a, perm=perm), perm=rev_perm), a))
## The "composed" 'perm' vector achieves identity:
perm[rev_perm]
#> [1] 1 2 NA 4
## Sanity checks:
perm <- seq_len(10)
stopifnot(identical(build_rev_perm(perm), perm))
perm <- c(2:5,1L)
rev_perm <- build_rev_perm(perm)
stopifnot(identical(perm[rev_perm], seq_along(perm)))
perm <- c(5L,NA,2:4,NA,NA,1L)
rev_perm <- build_rev_perm(perm, n=6)
stopifnot(identical(perm[rev_perm], c(1:5,NA)))