灵活地连接单元格

Concatenate cells flexibly

我有一个结构 P,其中包含不同数量的单元格。例如,P.Block1.onsetsP.Block2.onsetsP.Block3.onsets, P.Block4.onsets,等。起始为1x16个细胞(即有16个细胞),每个单元格包含 1x4 双。所以 P.Block1.onsets{1,2} 可能是这样的 [12, 37, 108, 226]。 P 仅包含字段 BlockX,没有其他内容。块是结构,只包含字段 'onsets',没有其他内容。我想连接所有起始单元格。我可以这样做:

all_onsets=vertcat(P.Block1.onsets,P.Block2.onsets,P.Block3.onsets,P.Block4.onsets);  

但是,块的数量是可变的,有时说我有4个,其他时候可能有6个或8个。有什么办法可以灵活地做vertcat吗?输出 all_onsets 应该是 nx1,n 是 16 x no。块。我希望这是有道理的。

非常感谢!

如果所有的字段名都以Block开头,那么可以使用fieldnames函数动态提取所有的字段名,然后我们可以循环遍历每个字段,访问onsets 嵌套字段并连接我们的结果:

names = fieldnames(P);
all_onsets = [];
for idx = 1 : numel(names)
    all_onsets = vertcat(all_onsets, P.(names{idx}).onsets);
end

第一行代码提取所有字段名称并将它们存储到元胞数组中。接下来,我们将 all_onsets 初始化为空数组,然后对于结构中的每个字段名称,我们获取名称以 Block 开头的字段,然后访问 onsets 嵌套字段并连接这到 all_onsets。请特别注意我访问 P 的方式。我们可以创建与您想要的字段一致的 动态 字符串。最后,我们将所有 onsets 个子字段矩阵连接成一个大元胞数组。

all_onsets 的结果将如下所示:

>> all_onsets
all_onsets = 
    [1x4 double]
    [1x4 double]
    [1x4 double]
    [1x4 double]
    ...

首先创建一些假数据。

P.Block1.onsets = {[1, 37, 108, 226] [2, 37, 108, 226]}';
P.Block2.onsets = {[3, 37, 108, 226] [4, 37, 108, 226]}';

然后将 P 的字段(所有这些块)更改为一个单元格。

P = struct2cell( P );

然后您可以使用 cellfun 将每个块的起点转换为矩阵。您的输出将是 nx4 矩阵的垂直单元格。您需要 cell2mat 将它们连接并转换为矩阵。

A = cell2mat( cellfun( @(C) cell2mat( C.onsets ), P, 'UniformOutput', false ) );

我的代码生成以下输出。

cellfun =>
    [2x4 double]
    [2x4 double]
>> cell2mat(A)
ans =
     1    37   108   226
     2    37   108   226
     3    37   108   226
     4    37   108   226

如果你想将矩阵转换为单元格,你可以使用我的rows2cell.m function

创建一个结构数组以删除 Block* 字段,然后在结果数组中引用 onsets 字段以获得逗号分隔列表并使用 vertcat:

Q = structfun(@deal, P);
all_onsets = vertcat(Q.onsets);