Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

data.frame with a column containing a matrix in R

Tags:

dataframe

r

I'm trying to put some matrices in a dataframe in R, something like :

m <- matrix(c(1,2,3,4), nrow=2, ncol=2)
df <- data.frame(id=1, mat=m)

But when I do that, I get a dataframe with 2 rows and 3 columns instead of a dataframe with 1 row and 2 columns.

Reading the documentation, I have to escape my matrix using I().

df <- data.frame(id=1, mat=I(m))

str(df)
'data.frame':   2 obs. of  2 variables:
 $ id : num  1 1
 $ mat: AsIs [1:2, 1:2] 1 2 3 4

As I understand it, the dataframe contains one row for each row of the matrix, and the mat field is a list of matrix column values.

Thus, how can I obtain a dataframe containing matrices ?

Thanks !

like image 870
Scharron Avatar asked May 26 '11 19:05

Scharron


People also ask

Can a data frame have a column that is a matrix?

Data frames with matrix columns are a very useful solution to this situation. The posterior stays in a matrix that has the same number of rows as the data frame. But that matrix only is recognized as a single "column" in the data frame, and referring to that column using df$mat will return the matrix.

How do I make a matrix into a Dataframe in R?

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 I select a column of a matrix in R?

To get a specific column of a matrix, specify the column number preceded by a comma, in square brackets, after the matrix variable name. This expression returns the required row as a vector.

Can a list contain a matrix in R?

Lists are objects that may contain elements of different types, similar to vectors. These different types can be of strings, numbers, vectors, and even another list inside. You can have matrices as different elements in your lists.


3 Answers

I find data.frames containing matrices mind-bendingly weird, but: the only way I know to achieve this is hidden in stats:::simulate.lm

Try this, poke through and see what's happening:

d <- data.frame(y=1:5,n=5)
g0 <- glm(cbind(y,n-y)~1,data=d,family=binomial)
debug(stats:::simulate.lm)
s <- simulate(g0,n=5)

This is the weird, back-door solution. Create a list, change its class to data.frame, and then (this is required) set the names and row.names manually (if you don't do those final steps the data will still be in the object, but it will print out as though it had zero rows ...)

m1 <- matrix(1:10,ncol=2)
m2 <- matrix(5:14,ncol=2)
dd <- list(m1,m2)
class(dd) <- "data.frame"
names(dd) <- LETTERS[1:2]
row.names(dd) <- 1:5
dd
like image 80
Ben Bolker Avatar answered Oct 21 '22 00:10

Ben Bolker


A much easier way to do this is to define the data frame with a placeholder for the matrix

m <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2) 
df <- data.frame(id = 1, mat = rep(0, nrow(m)))

Then to assign the matrix. No need to play with the class of a list or to use an *apply() function.

df$mat <- m
like image 43
adamleerich Avatar answered Oct 20 '22 23:10

adamleerich


I came across the same problem trying to understand the gasoline data in pls package. Used $ for the job. First, lets create a matrix, lets call it spectra_mat, then a vector called response_var1.

spectra_mat = matrix(1:45, 9, 5)
response_var1 = seq(1:9)

Now we put the vector response_var1 in a new data frame - lets call it df.

df = data.frame(response_var1)
df$spectra = spectra_mat

To check,

str(df)

'data.frame':   9 obs. of  2 variables:
 $ response_var1: int  1 2 3 4 5 6 7 8 9
 $ spectra      : int [1:9, 1:5] 1 2 3 4 5 6 7 8 9 10 ...
like image 27
zoc99 Avatar answered Oct 20 '22 22:10

zoc99