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 !
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.
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.
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.
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.
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
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
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 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With