0

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')
Daniel
  • 36,610
  • 3
  • 36
  • 69
johnsonzhj
  • 517
  • 1
  • 5
  • 23

1 Answers1

1

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
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Great, it works! Although the nested list is not supported, it works anyway. I've tested the script on matlab, the only incompatibility is that dot(".") is not supported in matlab as part of the variable name, so need to add one line to revised the names accordingly (names(data_list)<-gsub("\\.", "_", names(data_list))). – johnsonzhj Oct 02 '15 at 05:40