MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Summing values with database "group by" functionality

Asked by David on 4 May 2012

Tables in databases can easily be transformed by use of the "Group by" function.

Groups ususally occur on a common lable (such as state) while the data columns can be summed, averaged, counted, etc.

In the past, I've take matrices in matlab and dumped them into SQL tables where I can easily use this functionality.

This can take a long time to write the data andif it can be done in Matlab, before writign teh data, it would save considerable time.

Is there a way to do this in MatLab directly?

Products

No products are associated with this question.

Answer by Sean de Wolski on 4 May 2012
```doc accumarray
```

Answer by per isakson on 4 May 2012

In the Statistical toolbox there is a class named Dataset. It has a method grpstats.

```    grpstats
Class: dataset
Summary statistics by group for dataset arrays```

I think that does exactly what you ask for and more.

With plain matlab I'm convinced that data in a cell array, a for loop and some logical indexing will do the job. If you provide a toy example of data someone here will give you a piece of code, which demonstrates the approach.

--- CONT. ---

Study the Statistical toolbox Exampel: "Using Dataset Arrays"

--- CONT. 2012-05-07 ---

@David: This "file" is a mess.

1. There are seven column headers or is it five?
2. The first and second data row each contains eight values.
3. The third data row contains nine values.
4. Both comma and space are used as list separators

Additional information is needed. How to identify "missing values", etc.. Or is space not a separator but part of text values? You tell me.

per isakson on 4 May 2012

Is this copy&pasted from some text file?

Walter Roberson on 7 May 2012

Looks to me as if comma is used as a decimal grouping in this file.

per isakson on 8 May 2012

@Walter, yes indeed.

Answer by Peter Perkins on 7 May 2012

David, your example data has a few problems, notably the percent signs. Without having any details about what you are trying to do (and in particular how you might want to define groups in your data), here is an example of what you might do. This example uses a dataset array, but since you have nothing but numeric data, there's no reason why you could not use grpstats on a matrix.

```>> % remove embedded spaces from last column header in file
>> % remove stray space from end of next to last line
>> data = dataset('File','tmp.dat','Delimiter',' ');
>> % remove the percent signs
>> data.ID = uint64(data.ID)/100;
>> data.Loss = str2double(strrep(data.Loss,'%',''))/100;
>> data.EL = str2double(strrep(data.EL,'%',''));
>> data
data =
Event    ID         Loss          Rate    EL
1949     44688717          0       14.2      9e-07
3216     34845443    1.6e-07      574.8    4.7e-05
6443     33870362   8.65e-06      29301   0.002467
3721     31438262   6.04e-06      18995   0.001723
[snip]
570     15437760      3e-08       50.7    9.4e-06
3860     15242217    2.9e-07      435.2   8.14e-05
```
```>> data.LossGroup = ...
ordinal(data.Loss,{'High' 'Low'},[],[0,median(data.Loss),Inf])
data =
Event    ID          Loss      Rate   EL         LossGroup
1949     44688717          0    14.2     9e-07   High
3216     34845443    1.6e-07   574.8   4.7e-05   High
6443     33870362   8.65e-06   29301  0.002467   Low
3721     31438262   6.04e-06   18995  0.001723   Low
[snip]
570     15437760      3e-08    50.7   9.4e-06   High
3860     15242217    2.9e-07   435.2  8.14e-05   High
```
```>> lossGroupMeans = grpstats(data,'LossGroup','mean', ...
'DataVars',{'Rate' 'ELRelativeRate'})
lossGroupMeans =
LossGroup    GroupCount    mean_Rate    mean_EL
High    High         16            1837.7       0.00026079
Low     Low          17             49862        0.0082853
```

1 Comment

per isakson on 7 May 2012

Ok, comma serves as a thousand separator.

Answer by per isakson on 8 May 2012

Here is a solution that doesn't require the Statistical toolbox.

Separators:

1. list separator: space
2. thousand separator: comma
3. traling: %

Approach:

2. read the rest of the file to a string buffer
3. remove "," and "%" from the string buffer
4. read the string buffer with textscan
5. convert the cell array of double vectors to a double array
`    [ hdr, M ] = Read_text_file();`

The whole numbers in the file have been converted to "flints" (see Floating Points ). The mean of the "rows", for which Event==638, can be calculated with logical indexing.

`    mean( M( M(:,1)==638, : ), 1 ) `

With "flint" it is safe to use "==". With floating point numbers one need to allow for rounding errors

`    mean( M( abs(M(:,5)-0.0024558) < epsilon, : ), 1 )`

where epsilon is some appropriate small number.

--- Attachment ---

`    function   [ hdr, M ] = Read_text_file()       `
```        fid = fopen( 'Read_text_file.txt', 'r' );
hdr = fgetl( fid );
str = fread( fid, '*char' );
sts = fclose( fid );       %#ok<NASGU>```
```        str( str == ',' ) = [];
str( str == '%' ) = [];```
```        cac = textscan( str, '%f%f%f%f%f' );
M   = [ cac{:} ];
end```