2

How can I create a data.frame in a single call where a column is an array?
I have tried the following ways but this did not give the expected result.

A <- array(1:8, c(2,2,2))

data.frame(id = 1:2, ar = A)        #Converts A to 4 columns - not wanted
data.frame(id = 1:2, ar = I(A))     #Error: arguments imply differing number of rows: 8, 14
list2DF(list(id=1:2, ar = list(A))) #Error: all variables should have the same length

Using I or list2DF will work for matrix data.frame with a column containing a matrix in R and for list Create a data.frame where a column is a list but not for array.
Currently I can create it only in two steps.

A <- array(1:8, c(2,2,2))

DF <- data.frame(id = 1:2)
DF[["ar"]] <- A
#DF["ar"] <- A   #Alternative
#DF[,"ar"] <- A  #Alternative
#DF$ar <- A      #Alternative

str(DF) #Desired result
#'data.frame':   2 obs. of  2 variables:
# $ id: int  1 2
# $ ar: int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8

For me it looks like that this is currently not really supported. When subsetting for a row it gives only the first element of the array but when doing this for a matrix it gives the corresponding row of the matrix.

DF <- data.frame(id = 1:2)
DF[["ar"]] <- array(1:8, c(2,2,2))
str(DF[1,])
#'data.frame':   1 obs. of  2 variables:
# $ id: int 1
# $ ar: int 1

DF <- data.frame(id = 1:2)
DF[["m"]] <- matrix(1:4, 2)
str(DF[1,])
#'data.frame':   1 obs. of  2 variables:
# $ id: int 1
# $ m : int [1, 1:2] 1 3

When using a tibble, creating and also subsetting works as expected. Is there a way to have similar behaviour in base?

A <- array(1:8, c(2,2,2))
TI <- tibble::tibble(id = 1:2, ar = A)

str(TI)
#tibble [2 × 2] (S3: tbl_df/tbl/data.frame)
# $ id: int [1:2] 1 2
# $ ar: int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8

TI[1,]
## A tibble: 1 × 2
#     id          ar
#  <int> <int[,2,2]>
#1     1         1 …
GKi
  • 37,245
  • 2
  • 26
  • 48

2 Answers2

3

Probably you can try within

> within(data.frame(id = 1:2), ar <- A)
  id ar.1 ar.2 ar.3 ar.4
1  1    1    3    5    7
2  2    2    4    6    8

and check the structure

> within(data.frame(id = 1:2), ar <- A) %>% str()
'data.frame':   2 obs. of  2 variables:
 $ id: int  1 2
 $ ar: int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
2

An option

`[<-`(data.frame(a = 1:2), "ar", value = A)

-output

> `[<-`(data.frame(a = 1:2), "ar", value = A) |> str()
'data.frame':   2 obs. of  2 variables:
 $ a : int  1 2
 $ ar: int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8
akrun
  • 874,273
  • 37
  • 540
  • 662