Reputation:
I have a 3D array of dimensions MxNxO. For each of the M arrays of dimensions NxO, I want to apply
a function myfunction
that takes as input a NxO array and return a NxO array.
If I do
apply(array, 1, myfunction)
the output is a 2D array of dimension (N*O)xM instead of a 2D array of dimensions MxNxO.
As an example, we can use the identity
function from R.
Here is a 3D array
> a <- array(1:20, c(2,2,5))
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
, , 3
[,1] [,2]
[1,] 9 11
[2,] 10 12
, , 4
[,1] [,2]
[1,] 13 15
[2,] 14 16
, , 5
[,1] [,2]
[1,] 17 19
[2,] 18 20
and the apply
result should be the same (for my needs) but it is a 2D array instead:
> apply(a,1,identity)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
[4,] 7 8
[5,] 9 10
[6,] 11 12
[7,] 13 14
[8,] 15 16
[9,] 17 18
[10,] 19 20
Also, I would like to preserve the labels on each dimension of the array (myfunction
itself preserves those labels).
Upvotes: 2
Views: 361
Reputation: 52647
If you know the dimensions that your function will be returning (as you do in your trivial example), then you can us vapply
. I also would have suggested aaply
, though I prefer the result to be 2 2x5 matrices, not 5 2x2 matrices (since a[1, ,]
is a 2x5 matrix, so this makes more sense to me).
dim <- c(x=2,y=2,z=5)
dim.n <- lapply(1:length(dim), function(x) paste(names(dim)[x], seq(len=dim[x]), sep="_"))
a <- array(1:20, dim, dim.n)
vapply(dimnames(a)[[1]], function(i) identity(a[i, ,]), a[1, ,])
# , , x_1
#
# z_1 z_2 z_3 z_4 z_5
# y_1 1 5 9 13 17
# y_2 3 7 11 15 19
#
# , , x_2
#
# z_1 z_2 z_3 z_4 z_5
# y_1 2 6 10 14 18
# y_2 4 8 12 16 20
Main advantage of this is it's all base package, so you don't need to include plyr
. The plyr
answer is fine so long as you're okay with the interpretation of what the return dimensions should be, or don't necessarily know ahead of time the result format.
Also, I recognize the format here is nowhere near as clean as aaply
, and wish apply
respected the dimensions so one didn't need to resort to these things. I had a very similar question last week.
Upvotes: 0
Reputation: 173577
You are probably looking for aaply
in the plyr package:
a <- array(1:20, c(2,2,5))
> aaply(a,1,identity)
, , = 1
X1 1 2
1 1 3
2 2 4
, , = 2
X1 1 2
1 5 7
2 6 8
, , = 3
X1 1 2
1 9 11
2 10 12
, , = 4
X1 1 2
1 13 15
2 14 16
, , = 5
X1 1 2
1 17 19
2 18 20
Upvotes: 2