I would like to do a calculation in each cell of a cell array in Octave: 1) get the number of occurrences of the mode in each cell, and 2) divide this value by the length of the array in each cell.
e.g.,
A=1×2 cell array {[1 2 3 1 1]} {[1 1 1 1]};
the number of occurrences of the mode is 3 and 4,divided by the length of the array in each cell 5 and 4, it should be calculated as 3/5 4/4 in the cells, respectively.
If I use cellfun like this
m=cellfun(@(x) mode(x)./length(x),A);
the part of the function "mode(x)" return the mode of the array rather than the number of occurrence, because the number of occurrence can only be got by
[m, f, c] = mode (A)
where f is the number of occurrence of the mode.
How can I return f in cellfun to do the calculation? Thank you
what version of Octave are you using?
Testing with version 9.1.0, the mode
function does have a form where it returns the number of instances of the mode:
>> help mode
-- M = mode (X)
-- M = mode (X, DIM)
-- [M, F, C] = mode (...)
...
The return variable F is the number of occurrences of the mode in
the dataset.
>> [a,b,c] = mode([1 2 3 1 1])
a = 1
b = 3
c =
{
[1,1] = 1
}
now, because it's the second return variable, it would be troublesome to make a one-line anonymous function to get it. If that's not a requirement, you can do:
A = {[1 2 3 1 1]; [1 1 1 1]}
A =
{
[1,1] =
1 2 3 1 1
[2,1] =
1 1 1 1
}
>> [~,f,~] = cellfun (@mode, A) ## ~ tells Octave to ignore that output.
f =
3
4
>> L = cellfun (@length, A)
L =
5
4
>> m = f./L
m =
0.6000
1.0000
If you really want a one-line anonymous function, we can note that the mode elements locations can be found with find
, and then numel
will give us the incidence count. so the [~,f,~]
output can be replaced by something like:
>> f = cellfun(@(x) numel(find(x==mode(x))), A)
f =
3
4
so that can be combined with numel
to make:
>> m = cellfun(@(x) numel(find(x==mode(x)))/numel(x), A)
m =
0.6000
1.0000
Normally anonymous functions in Octave introduce a significant slowdown, but so does calling cellfun
. A quick timing test shows that the 1-line anonymous function is only bit slower than the direct function calls with two calls to cellfun
:
tic; for idx = 1:100, m = cellfun(@(x) numel(find(x==mode(x)))/numel(x), A);endfor, toc
Elapsed time is 0.250258 seconds.
>> tic; for idx = 1:1000, [~,f,~] = cellfun (@mode, A); L = cellfun(@numel, A);m = f./L; endfor, toc
Elapsed time is 0.236082 seconds.
(numbers above chosen as consistent values from multiple tests.)