Reputation: 197
I have a dataframe "df", and I would like to transform it into an array BY ROW, for example:
> df
x y
1 1 21
2 2 22
3 3 23
4 4 24
5 5 25
6 6 26
7 7 27
8 8 28
#Into this array:
> array.df
, , 1
[,1] [,2] [,3] [,4]
[1,] 1 21 2 22
[2,] 3 23 4 24
, , 2
[,1] [,2] [,3] [,4]
[1,] 5 25 6 26
[2,] 7 27 8 28
Can anyone help me with the code? Thanks.
Upvotes: 1
Views: 1452
Reputation: 93803
Just thought of a simpler base R answer for this using some array manipulation:
apply(array(t(df), dim=c(4,2,2)), c(1,3), t)
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 21 2 22
#[2,] 3 23 4 24
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 5 25 6 26
#[2,] 7 27 8 28
Use some matrix
trickery to fill by row and then reshape again. sapply
's simplify="array"
ensures the array
output:
sapply(
split(df, rep(1:2,each=nrow(df)/2)),
function(x) matrix(c(matrix(unlist(x),byrow=TRUE,ncol=2)),nrow=2),
simplify="array"
)
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 21 2 22
#[2,] 3 23 4 24
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 5 25 6 26
#[2,] 7 27 8 28
Upvotes: 0
Reputation: 1892
Using only the base package:
df <- data.frame(x = 1:8, y = 21:28)
array.df <- array(
data = as.vector(t(df)),
dim = c(4,2,2))
array.df <- aperm(a = array.df, perm = c(2,1,3))
print(array.df)
Upvotes: 1
Reputation: 307
Here is another not so elegant solution:
df <- data.frame(x=1:8, y=21:28)
vec <- as.vector(t(df)) # transpose df and then turn into a single vector
arr <- array(vec, dim=c(4,2,2)) # create array with first 2 dimensions transposed
lis <- lapply(1:2, function(x) { t(arr[,,x]) }) # transpose the first 2 dimensions
array(do.call(cbind, lis), c(2,4,2)) # convert back to array format
, , 1
[,1] [,2] [,3] [,4]
[1,] 1 21 2 22
[2,] 3 23 4 24
, , 2
[,1] [,2] [,3] [,4]
[1,] 5 25 6 26
[2,] 7 27 8 28
Upvotes: 1
Reputation: 13274
Quite an ugly solution, but it gets the job done. Maybe someone else has a better way of doing this. In the meantime, it should do.
install.packages("reshape2")
library("reshape2")
df
x y
1 1 21
2 2 22
3 3 23
4 4 24
5 5 25
6 6 26
7 7 27
8 8 28
myarray <- array(cbind(matrix(melt(t(df))[1:8,3],byrow = T, ncol = 4),matrix(melt(t(df))[9:16,3],byrow = T, ncol = 4)), c(2,4,2))
, , 1
[,1] [,2] [,3] [,4]
[1,] 1 21 2 22
[2,] 3 23 4 24
, , 2
[,1] [,2] [,3] [,4]
[1,] 5 25 6 26
[2,] 7 27 8 28
The idea is to transpose the data frame with t()
and then melt it using the melt()
function from the reshape2
package. Upon reshaping the data, you want to grab the 3rd column and then create two matrices from it by row. Then, you will need to cbind
those matrices into one matrix. And finally, use that matrix to get the array you want with dimension c(2,4,2)
.
I hope this makes sense.
Upvotes: 1