1
votes

I am trying to take the mean of select values in a matrix column, selecting them by their value in a different column.

For example:

X=[1950     1;
   1950     2;
   1950     3;
   1951     1;
   1951     5;
   1952     1]

I want to take the mean of the values per each year - essentially, select values with the same column 1 value, and then take the mean of the corresponding column 2 values. So the mean value for 1950 would be 2, the mean value for 1951 would be 1. I can do this manually by creating a vector for each year value and then taking the mean of the whole vector, but this is impractical for greater amounts of data. The number of data points for each year varies, so I don't think I can use reshape to do this.

2
See also this similar question and a related question on weighted means.chappjc

2 Answers

6
votes

You want accumarray:

[~, ~, ii ] = unique(X(:,1));
result = accumarray(ii, X(:,2), [], @mean);

I suggest you read the documentation of accumarray thoroughly to see how this works. It's a very powerful and flexible function.

1
votes

Give this a try:

X=[1950 1; 1950 2; 1950 3; 1951 1; 1951 5; 1952 1];

years = unique(X(:,1));

for ii=1:length(years)
    yr_index = find(X == years(ii));
    yr_avg(ii) = mean(X(yr_index,2));
end

This will find all the unique year entries. It will then step through each year, find the rows which correspond to the specific year, and take a mean of the second column of just those rows. It will save the mean in the yr_avg vector. Each year entry in the years vector should have a corresponding mean in the yr_avg vector.