Search code examples
rmat-file

how to convert nest list into structure(.mat) in matlab


I found rmatio is a nice tool to convert data frame and list into .mat file (although it seems that the character is not supported), but in the following demo, I want to generate a nested list called data_list, but when I use write.mat to export it as a .mat file, only the first column of the data is reserved, see how can I solve such a problem? Thanks in advance.

library(rmatio)  
data(iris)
iris
iris$group<-paste("group",rep(1:2,75),sep="")

names(iris)<-c('a','b','c','d','species','group')
## "."is not support as name in .mat file, so I rename it as "a b c d" for simplicity.
head(iris)
##split the data into list according to species.
out<-split(iris[,c(1:4,6)],f=iris$species)
out
##further split the data by group variable to create a nest list.
data_list<-lapply(out,function(x){
split(x,f=x$group)
})

write.mat(data_list, 'iris.mat')

Solution

  • After installing and loading Octave and learning a couple of commands and experimenting with the write.mat function, I have concluded that it does not handle nested lists. It apparently writes each item in a list to a separate variable in the matlab file. So if you want all of the data in iris (split into two groups) to go into a matlab file, and end up with separate variable written with rmatio you needs something like this:

    iris$group <- 1:2
    data_list <- 
    split(unlist(iris[1:4]), f=interaction(iris$Species, iris$group, rep(names(iris)[1:4], each=150)))
    str(data_list)
    write.mat(data_list, 'iris2.mat')
    

    Then in an Octave session you see:

    octave-3.4.0:19> load /Users/davidwinsemius/iris2.mat 
    octave-3.4.0:20> whos
    Variables in the current scope:
    
      Attr Name                           Size                     Bytes  Class
      ==== ====                           ====                     =====  ===== 
           setosa.1.Petal.Length          1x25                       200  double
           setosa.1.Petal.Width           1x25                       200  double
           setosa.1.Sepal.Length          1x25                       200  double
           setosa.1.Sepal.Width           1x25                       200  double
           setosa.2.Petal.Length          1x25                       200  double
           setosa.2.Petal.Width           1x25                       200  double
           setosa.2.Sepal.Length          1x25                       200  double
           setosa.2.Sepal.Width           1x25                       200  double
           versicolor.1.Petal.Length      1x25                       200  double
           versicolor.1.Petal.Width       1x25                       200  double
           versicolor.1.Sepal.Length      1x25                       200  double
           versicolor.1.Sepal.Width       1x25                       200  double
           versicolor.2.Petal.Length      1x25                       200  double
           versicolor.2.Petal.Width       1x25                       200  double
           versicolor.2.Sepal.Length      1x25                       200  double
           versicolor.2.Sepal.Width       1x25                       200  double
           virginica.1.Petal.Length       1x25                       200  double
           virginica.1.Petal.Width        1x25                       200  double
           virginica.1.Sepal.Length       1x25                       200  double
           virginica.1.Sepal.Width        1x25                       200  double
           virginica.2.Petal.Length       1x25                       200  double
           virginica.2.Petal.Width        1x25                       200  double
           virginica.2.Sepal.Length       1x25                       200  double
           virginica.2.Sepal.Width        1x25                       200  double
    
    Total is 600 elements using 4800 bytes
    

    There was an R.matlab-package that did the transfer of the dataframe iris with a less Baroque process:

    > require(R.matlab)
    Loading required package: R.matlab
    R.matlab v3.2.0 (2015-02-24) successfully loaded. See ?R.matlab for help.
    
    Attaching package: ‘R.matlab’
    
    The following objects are masked from ‘package:base’:
    
        getOption, isOpen
    
    > writeMat("iris3.mat", iris=iris, matVersion="5", onWrite=NULL, verbose=FALSE)
    

    Which transferred a single object with 6 named columns.It was also able to transfer the data_list structure as a single item that had 24 columns.

    octave-3.4.0:35> load /Users/davidwinsemius/dl.mat 
    octave-3.4.0:36> whos
    Variables in the current scope:
    
      Attr Name           Size                     Bytes  Class
      ==== ====           ====                     =====  ===== 
           data_list      1x1                       4800  struct
           iris           1x1                       4800  struct
    
    Total is 2 elements using 9600 bytes