Average matrices based on unique value in structure resulting in a new structure

I have a structure IMERG, with 19 fields. I have a field called "UID" based on which I want to average the fields of Lat and Lon which are 1*1700. For example, If UID is 1, then want to average all the Lat's with UID = 1 such that I get an 1 * 1700 for UID =1, and similarly for others.
I tried using arrayfucn, but it averages all the values within each IMERG(1).Lat, and also I'm unable to evaluate it based on unique values of UID. Please find the data attached of the structure I'm using.
A = arrayfun(@(x) mean(x.Lat),IMERG,'UniformOutput',1),
Any help is highly appreciated !! I have been trying this for very long now....

 Réponse acceptée

How about using splitapply function, like:
IMERG = struct2table(IMERG);
avgLat = splitapply(@(x) {mean([x{:}],2)}, IMERG.Lat, IMERG.TimeID+1);

4 commentaires

The following error is shown,
Error using splitapply (line 111) For N groups, every integer between 1 and N must occur at least once in the vector of group numbers.
Please find the data attached. I want to average the data based on "UID" which is a unique number generated as a 3hr average for each day. Also, is there any way to form a new structure with average of not just Lat but other variables as well (I know its looks empty now). But I want an average of all fields based on UID.
This error occurs when a group number in your data (i.e IMERG.UID) is not integer between 1 and N. To avoid this, you can use findgroups function. The following is an example.
group = findgroups(IMERG.UID);
avgLat = splitapply(@(x) {mean([x{:}],2)}, IMERG.Lat, group);
I would like to reply to your second question after looking at your MAT file.
OK, regarding a second question, it depends on what types of data will be stored in each element in your table.
If column vector with the same length will be stored in each element, like IMERG.LAT, you can use the same way.
If scalar value will be stored in each element, you can apply splitapply function with small modification, like:
avgValues = splitapply(@(x) {mean(x)}, IMERG{:,[p q r...]}, group);
where p,q, and r are column number where each element are scalar value.
Thank you much :) "If column vector with the same length will be stored in each element, like IMERG.LAT, you can use the same way" I wanted to perform simultaneous average of the fields according to IMERG.UID with the same length as the field and store them into a new structure. Thanks again !

Connectez-vous pour commenter.

Plus de réponses (1)

To obtain the result in structure type, please combine struct2table, splitapply and table2struct functions like the following:
load('IMERG.mat');
IMERG = struct2table(IMERG);
[group,UID] = findgroups(IMERG.UID);
avgLat = splitapply(@(x) {mean([x{:}],2)}, IMERG.Lat, group);
avgLon = splitapply(@(x) {mean([x{:}],2)}, IMERG.Lon, group);
avgIMERG = table(UID,avgLat,avgLon);
avgIMERG = table2struct(avgIMERG);
Using this code, averaged Lat and Lon, based on UID, will be stored in avgImerg structure.

Catégories

Community Treasure Hunt

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

Start Hunting!

Translated by