Joe C
Joe C

Reputation: 2827

How to travese a MATLAB table w/o creating a new table

I wanted to travel a table w/o creating a new table. MATLAB has a rowfun API. But it does not like a lambda with no return type. Is there a better to do so?

>> T = table({1;2;3})

T = 

Var1
____

[1] 
[2] 
[3] 

>> rowfun(@(x) display('') , T)
Error using table/rowfun>dfltErrHandler (line 338)
Applying the function '@(x)display('')' to the 1st row of A generated the following error:

Too many output arguments.


Error in      table/rowfun>@(s,varargin)dfltErrHandler(grouped,funName,s,varargin{:}) (line 200)
errHandler = @(s,varargin) dfltErrHandler(grouped,funName,s,varargin{:});

Error in table/rowfun (line 219)
            [b_data{i,:}] = errHandler(struct('identifier',ME.identifier, 'message',ME.message,
            'index',i),inArgs{:});

>> rowfun(@(x) x , T)

ans = 

Var1
____

[1] 
[2] 
[3] 

Upvotes: 0

Views: 90

Answers (1)

sco1
sco1

Reputation: 12214

Short story

Use the following syntax for calling rowfun if you don't expect an explicit output:

rowfun(@(x) display(''), T, 'NumOutputs', 0)

Given the following example:

T = table({1;2;3});

fprintf('rowfun:\n')
rowfun(@(x) display(''), T, 'NumOutputs', 0, 'OutputFormat', 'uniform');
fprintf('arrayfun:\n')
arrayfun(@(x) display(''), table2array(T))

We get a consistent return:

>> testcode
rowfun:
     ''

     ''

     ''

arrayfun:
     ''

     ''

     ''

Short story long

The error is based on rowfun expecting to have to provide an output in some kind of format (table, cell, etc.), so its default is to expect at least one output argument from the function handle it's using.

You can find the relevant portions in rowfun's source (open rowfun):

pnames = {'GroupingVariables' 'InputVariables' 'OutputFormat' 'NumOutputs' 'OutputVariableNames' 'SeparateInputs' 'ExtractCellContents'  'ErrorHandler'};
dflts =  {                []               []              2            1                    {}             true                 false              [] };
[groupVars,dataVars,outputFormat,nout,outNames,separateArgs,extractCells,errHandler,supplied] ...
    = matlab.internal.table.parseArgs(pnames, dflts, varargin{:});

and

try
    if nout > 0
        [b_data{i,:}] = fun(inArgs{:});
    else
        fun(inArgs{:});
    end
catch ME
    if nout > 0
        [b_data{i,:}] = errHandler(struct('identifier',ME.identifier, 'message',ME.message, 'index',i),inArgs{:});
    else
        errHandler(struct('identifier',ME.identifier, 'message',ME.message, 'index',i),inArgs{:});
    end
end

As you can see, the default number of outputs is 1 and, unless you call rowfun with an explicit 'NumOutputs', 0 NV pair, it's going to expect an output from display, which will obviously cause the error.

Upvotes: 3

Related Questions