【问题标题】:Importing a 3D array from Matlab to R将 3D 数组从 Matlab 导入到 R
【发布时间】:2017-04-21 21:17:26
【问题描述】:

我正在尝试将 Matlab 文件导入 R 进行一些分析。 matlab 文件是概率值的 3D 位置数组。因此,它是跨 z 个“切片”的 2D (x,y) 矩阵。我想做的是将其转换为具有“位置”的 R 文件,然后是报告的概率值。因此,将以下内容作为输出:

Prob    x    y    z
0.17    1    1    1
0.28    1    1    2
0.35    2    1    1
0.40    2    1    2
0.16    1    2    1
0.27    1    2    2
0.34    2    2    1
0.80    2    2    2

当我使用 R.matlab 包时,我可以导入数据,它似乎可以正常导入,但我似乎无法获得数据的“维度”或将其划分为不同的矩阵......或者真的做任何有用的事情,但让它显示为一个长的值“列表”,即行*列*切片的长度。

下面是一些示例代码:

Matlab 代码

x = rand(3,4,2)
save file.mat x

R 代码

Tdata <- readMat("file.mat") 
    head(Tdata)
    str(Tdata)
    length(Tdata$x)

哪些输出

> str(Tdata)
List of 1
$ x: num [1:3, 1:4, 1:2] 0.026 0.330 0.222 0.631 0.567 ...
- attr(*, "header")=List of 3
..$ description: chr "MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Mon Dec  5 17:45:33 2016                                        "
..$ version    : chr "5"
..$ endian     : chr "little"

> length(Tdata$x)
[1] 24

所以它表明 Tdata 是一个包含三个维度的数组的单个元素列表,每个维度都是正确的,并且它具有正确的值总数,但我似乎无法分离出任何这些列表或识别它们的尺寸使用 length() 或 dim() 函数。最初,我正在考虑使用类似下面的东西,但因为我无法获得它似乎不起作用的尺寸。

ndim <- dim(Tdata)
x_coord <- c(1:ndim[1])
y_coord <- c(1:ndim[2])
z_coord <- c(1:ndim[3])
    new_df <- expand.grid(x_coord,y_coord,z_coord)
    new_df <- cbind(new_df,Tdata$x)

任何帮助将不胜感激!

【问题讨论】:

  • 如果使用 Octave 作为中介,foreign::read.octave 可以直接读入数组。
  • 所以我尝试使用 read.octave("file.mat") 读取 .mat 文件,我收到此错误:开关错误(类型,矩阵 = read_octave_matrix(con),标量 = read_octave_scalar (con), : EXPR must be a length 1 vector 然后我尝试使用 data
  • 好点,我将更新文本以反映这一点。谢谢。

标签: r matlab multidimensional-array file-conversion


【解决方案1】:

对于显示的Tdata 对象,您可以使用Tdata$xTdata[[1]] 访问数组。不幸的是,我不知道有任何等效于矩阵函数rowcol。您可以使用一系列嵌套的rep-调用来构建索引。

rows = rep( rep( 1:dim(arr)[1], each=dim(arr)[3] ), times=dim(arr)[2])
cols= rep( rep( 1:dim(arr)[1], each=dim(arr)[3] ), each=dim(arr)[2])
instances= rep( rep( 1:dim(arr)[1], times=dim(arr)[3] ), times=dim(arr)[2])

然后这会返回一个对象(希望如此,但在没有dput-output 提供的示例的情况下未经测试。)

data.frame( Prob = Tdata$x, x=rows,y=cols, z=instances)

有一个函数可以生成包含唯一组合的行的数据帧,但您需要使用可能看起来不太直观的标签来调用它:

> expand.grid( z = 1:dim(arr)[1], x = 1:dim(arr)[2], y = 1:dim(arr)[3])
  z x y
1 1 1 1
2 2 1 1
3 1 2 1
4 2 2 1
5 1 1 2
6 2 1 2
7 1 2 2
8 2 2 2

基于对问题的误读的旧答案:

我的 rd.txt 函数只是将 read.table 参数设置为从带有标题的文本中读取以制作数据帧(我在为 read.table 创建 text-argument 之前完成了它):

> arr <- array(NA, c(2,2,2) )
> df <- rd.txt("Prob    x    y    z
+ 0.17    1    1    1
+ 0.28    1    1    2
+ 0.35    2    1    1
+ 0.40    2    1    2
+ 0.16    1    2    1
+ 0.27    1    2    2
+ 0.34    2    2    1
+ 0.80    2    2    2
+ ")

现在,使用矩阵索引方法来寻址数组(或更常见的矩阵)中的位置:

> arr[ as.matrix(df[-1]) ] <- df[[1]]
> arr
, , 1

     [,1] [,2]
[1,] 0.17 0.16
[2,] 0.35 0.34

, , 2

     [,1] [,2]
[1,] 0.28 0.27
[2,] 0.40 0.80

R 的稀疏矩阵 Matrix 包也使用了 val、i、j 格式(感谢 Martin Maechler)。

【讨论】:

  • 我认为你做的与我想做的完全相反。我想从 3D 矩阵转到文本文件。我所拥有的是一个 3D 概率数组,我需要转到一个文本文件(或 csv 或任何标准格式),它是 x、y、z 坐标(矩阵位置)和该矩阵坐标处的概率。
  • 我会改变答案。这要简单得多。
  • 真正的问题是我在导入 .mat 文件时遇到问题。如上所述,当我导入 .mat 文件时,它是一个 3D 数组,但我无法使用我知道的函数获得它的任何尺寸。没有维度,我无法生成索引和分配值。实际上,我将导入数百到数千个这些文件,每个文件的大小都不同。所以我需要一种方法来识别从 matlab 导入的未知数组的维度(dim()、length() 和 nrow() 或 ncol() 都只给出 1 的值)或者能够访问它的索引并得到每个索引位置的值。
  • 如果您提供dput(Tdfata) 的输出,我将有一些工作要做。因为它是我只能去你的错误报告。在这一点上,我猜你需要首先使用以下代码分配一个名为 arr 的对象:arr &lt;- Tdata[[1]]
  • 啊!你是个天才。这就是我所需要的。现在 arr 是一个普通数组,我可以调用 dim 并获取维度。谢谢您的帮助。现在,用于索引。这些文件最终将是巨大的,尽管示例是一个小的 3D 数组。你知道从 3D 概率数组到 4 列 (x,y,z,prob) 矩阵的计算效率最高的方法吗?其中 x、y 和 z 是数组位置,prob 是该位置的值?
猜你喜欢
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
相关资源
最近更新 更多