Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R - store a matrix into a single dataframe cell

Tags:

dataframe

r

I'm trying to store an entire matrix/array into a single cell of a data frame, but can't quite remember how to do it.

Now before you say it can't be done, I'm sure I remember someone asking a question on SO where it was done, although that wasn't the point of the question so I can't find it again.

For example, you can store matrices inti a single cell of a matrix like so:

myMat <- array(list(), dim=c(2, 2))
myMat[[1, 1]] <- 1:5
myMat[[1, 2]] <- 6:10

#     [,1]      [,2]     
#[1,] Integer,5 Integer,5
#[2,] NULL      NULL

The trick was in using the double brackets [[]].

Now I just can't work out how to do it for a data frame (or if you can):

# attempt to make a dataframe like above (except if I use list() it gets
# interpreted to mean the `m` column doesn't exist)
myDF <- data.frame(i=1:5, m=NA)
myDF[[1, 'm']] <- 1:5
# Error in `[[<-.data.frame`(`*tmp*`, 1, "m", value = 1:5) : 
#  more elements supplied than there are to replace

# this seems to work but I have to do myDF$m[[1]][[1]] to get the 1:5,
# whereas I just want to do myDF$m[[1]].
myDF[[1, 'm']] <- list(1:5)

I think I'm almost there. With that last attempt I can do myDF[[1, 'm']] to retrieve list(1:5) and hence myDF[[1, 'm']][[1]] to get 1:5, but I'd prefer to just do myDF[[1, 'm']] and get 1:5.

like image 874
mathematical.coffee Avatar asked Nov 22 '12 01:11

mathematical.coffee


People also ask

How do you save a matrix as a Dataframe in R?

A matrix can be converted to a dataframe by using a function called as. data. frame(). It will take each column from the matrix and convert it to each column in the dataframe.

How do you convert a matrix into a data frame?

Convert a Data Frame into a Numeric Matrix in R Programming – data. matrix() Function. data. matrix() function in R Language is used to create a matrix by converting all the values of a Data Frame into numeric mode and then binding them as a matrix.

How do you store a matrix?

In the computer memory, all elements are stored linearly using contiguous addresses. Therefore, in order to store a two-dimensional matrix a, two dimensional address space must be mapped to one-dimensional address space. In the computer's memory matrices are stored in either row-major or column-major order form.


2 Answers

I think I worked it out. It is important to initialise the data frame such that the column is ready to accept matrices.

To do this you give it a list data type. Note the I to protect the list().

myDF <- data.frame(i=integer(), m=I(list()))

Then you can add rows as usual

myDF[1, 'i'] <- 1

and then add the matrix in with [[]] notation

myDF[[1, 'm']] <- matrix(rnorm(9), 3, 3)

Access with [[]] notation:

> myDF$m[[1]]
          [,1]       [,2]       [,3]
[1,] 0.3307403 -0.2031316  1.5995385
[2,] 0.4588922  0.1631086 -0.2754463
[3,] 0.0568791  1.0358552 -0.1623794

To initialise with non-zero rows you can do (note the I to protect the vector and the vector('list', 5) to initialise an empty list of length 5 to avoid wasting memory):

myDF <- data.frame(i=1:5, m=I(vector('list', 5)))
myDF$m[[1]] <- matrix(rnorm(9), 3, 3)
like image 190
mathematical.coffee Avatar answered Sep 29 '22 13:09

mathematical.coffee


I think the trick may be to insert it in as a list:

set.seed(123)
dat <- data.frame(women, m=I(replicate(nrow(women), matrix(rnorm(4), 2, 2), 
                simplify=FALSE)))


str(dat)
'data.frame':   15 obs. of  3 variables:
 $ height: num  58 59 60 61 62 63 64 65 66 67 ...
 $ weight: num  115 117 120 123 126 129 132 135 139 142 ...
 $ m     :List of 15
  ..$ : num [1:2, 1:2] -0.5605 -0.2302 1.5587 0.0705
  ..$ : num [1:2, 1:2] 0.129 1.715 0.461 -1.265
  ...
  ..$ : num [1:2, 1:2] -1.549 0.585 0.124 0.216
  ..- attr(*, "class")= chr "AsIs"

dat[[1, "m"]]
           [,1]       [,2]
[1,] -0.5604756 1.55870831
[2,] -0.2301775 0.07050839

dat[[2, "m"]]
          [,1]       [,2]
[1,] 0.1292877  0.4609162
[2,] 1.7150650 -1.2650612

EDIT: So the question really is about initialising and then assigning. Given that, you should be able to define a data.frame like the one in your question like so:

data.frame(i=1:5, m=I(vector(mode="list", length=5)))

You can then assign to it like so:

dat[[2, "m"]] <- matrix(rnorm(9), 3, 3)
like image 34
sebastian-c Avatar answered Sep 29 '22 12:09

sebastian-c