How do I use 'ErrorHandler' in arrayfun?

x = arrayfun(@(x) mean(x.Num(1:20,3)), Struct, 'UniformOutput', false)
Struct is a 1x45 structure containing a field called Num, which is an array of integers.
I want to take the mean of the first 20 numbers in the third column pf each of the 45 Num fields, but the problem is that a few of the Num fields have fewer than 20 rows. So when I try to run this, Matlab gives me an error saying "Index exceeds matrix dimensions"
How can I use the ErrorHandler to make the mean = 0 when Num has fewer than 20 numbers in the third column?

 Respuesta aceptada

Jacob Halbrooks
Jacob Halbrooks el 15 de En. de 2014
Rather than use ErrorHandler here, consider writing your logic into a function that acts on a scalar struct. This function would check the input struct's Num field size to determine whether to return a mean calculation or 0. Here is an example:
function v = meanMyStruct(s)
sNum = s.Num;
if size(sNum,1) >= 20
v = mean(sNum(1:20,3));
else
v = 0;
end
Now you can use this function with ARRAYFUN on your struct array:
s = struct('Num',{rand(20,5), rand(19,5), rand(21,5)});
out = arrayfun(@meanMyStruct, s)

3 comentarios

Michael
Michael el 16 de En. de 2014
Ah thanks, that makes sense. Now what if I wanted to, instead of finding the mean of the first 20 numbers, find the mean for all of the numbers in the third column when the number in the first column was less than 20? So for example, say that two of the Num fields are:
1 2 4
17 4 6
19 9 8
25 10 18
and
3 6 10
12 8 14
30 7 1
33 3 8
I would want the mean of the first to be: (4+6+8)/3 = 6 because 1, 17 and 19 are less than 20. I would want the mean of the second to be (10+14)/2 = 12 because 3 and 12 are less than 20. I can't seem to figure out a way to do this. Since all of the numbers in the first column increase as you go down the rows, I was thinking of trying to find the row number of the first number greater than 20 in the first column, and calculate the mean of the numbers in the third column up until that row number, but I don't know how to go about doing this
Using the first data as an example:
sNum = [1 2 4; 17 4 6; 19 9 8; 25 10 18];
You can then get just the first column and create a logical mask of the rows that fit your condition:
firstColumn = sNum(:,1);
rowsUnder20 = firstColumn <20;
Now you can use the logical mask to select just the data you want:
sNumNew = sNum(rowsUnder20,:);
disp(sNumNew)
1 2 4
17 4 6
19 9 8
So now just take the mean of the third row of sNumNew:
mean(sNumNew(:,3))
Michael
Michael el 25 de En. de 2014
thank you very much, that works perfectly.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Preguntada:

el 15 de En. de 2014

Comentada:

el 25 de En. de 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by