# Mean command gives wrong answer

4 views (last 30 days)
SS on 27 May 2020
Commented: SS on 27 May 2020
Hi. I want to calculate the mean of a data and the mean command gives wrong result. Below is the code. I should get 160 but, the code gives 21. Can someone hlep me finding the miskate.
Thanks.
x=[1,2,3,4,5,6,7,8,9,10,11,12]; % x values
y=[15,120,2,30,40,150,60,170,80,9,15,1000]; % y values
idx1 = x > 3 & x < 10; % specific x values
idx = y(idx1) >= 150; % specific y values
a=mean(y(idx))

per isakson on 27 May 2020
Analyze this
%%
x=[1,2,3,4,5,6,7,8,9,10,11,12]; % x values
y=[15,120,2,30,40,150,60,170,80,9,15,1000]; % y values
%%
idx1 = find( x > 3 & x < 10 ); % specific x values
idx = find( y(idx1) >= 150 ); % specific y values
%%
a = mean(y(idx1(idx)))
a =
160

#### 1 Comment

SS on 27 May 2020
Thank you.

John D'Errico on 27 May 2020
Edited: John D'Errico on 27 May 2020
No. the code gives the correct answer in terms of what you wrote. That the code you wrote does not solve the problem you want to solve is a bug in the programmer, not MATLAB. I'll concede the problem you tripped over was a subtle one though.
x=[1,2,3,4,5,6,7,8,9,10,11,12]; % x values
y=[15,120,2,30,40,150,60,170,80,9,15,1000]; % y values
idx1 = x > 3 & x < 10; % specific x values
idx = y(idx1) >= 150; % specific y values
I'll now look more carefully at which elements were selected. Effectively, idx1 tells us which elements of x are GREATER than 3, but less than 10,
x(idx1)
ans =
4 5 6 7 8 9
Of those 6 elements that we located in x, what values of y did we find?
y(idx1)
ans =
30 40 150 60 170 80
And now, admittedly, you THINK you can now use y(idx). But IDX is a logical vector, of length 6.
y(idx)
ans =
2 40
Which elements did y(idx) single out? It did not find the two elements you want it to find. And the mean of the vector [2 40] is indeed 21. So MATLAB did what you told it to do.
The problem is, you cannot use logical indices the way you might think. You also need to beware of composing logical indices. So this call does not work:
y(idx1(idx))
ans =
120
Had we written idx1 using find?
idx1 = find(x > 3 & x < 10);
idx = y(idx1) >= 150; % specific y values
Now this works.
y(idx1(idx))
ans =
150 170
mean(y(idx1(idx)))
ans =
160
But your fundamental problem was in not seeing that idx is essentially a RELATIVE REFERENCE into the set you created using the first test. You cannot use the logical vector idx to index into the original vector y.

#### 1 Comment

SS on 27 May 2020
Thanks for the detailed comment.

KSSV on 27 May 2020
You should change the value of y as your are changing the indices.
x=[1,2,3,4,5,6,7,8,9,10,11,12]; % x values
y=[15,120,2,30,40,150,60,170,80,9,15,1000]; % y values
idx1 = x > 3 & x < 10; % specific x values
idx = y(idx1) >= 150; % specific y values
y = y(idx1) ;
a=mean(y(idx))

#### 1 Comment

SS on 27 May 2020
Thank you.