Cumulative sum by group
    9 Ansichten (letzte 30 Tage)
  
       Ältere Kommentare anzeigen
    
Hi, Could someone explain how to compute the running sum by group (without using for loop)? A example is: groupid = [1; 1; 1; 2; 2; 3; 3;]; value=[1;2;3;4;5;6;7]. the desired result is: runsum = [1;3;6; 4;9; 6;13]. Thanks a lot. zppine
0 Kommentare
Antworten (4)
  Sean de Wolski
      
      
 am 27 Jul. 2012
        
      Bearbeitet: Sean de Wolski
      
      
 am 27 Jul. 2012
  
      Using a for-loop here may be your best option. However, my unconditional love for accumarray forces me to present you with this:
groupid = [1; 1; 1; 2; 2; 3; 3;]; 
value=[1;2;3;4;5;6;7]; 
gcs = cell2mat(accumarray(groupid,value,[],@(x){cumsum(x)}))
0 Kommentare
  Daniel
 am 3 Jul. 2015
        function S = labeledCumsum(X,L)
% e.g. X=[3   5 8  9 1  2    5    8 5  4  9   2]
%      L=[0   1 1  2 2  0    0    1 1  1  0   5]
% result=[NaN 5 13 9 10 NaN  NaN  8 13 17 NaN 2]
L = L(:);
X = X(:);
if numel(L) ~= numel(X)
    error('The two inputs should be vectors of the same length.')
end
% Do the full cumulative sum
X(isnan(X)) = 0;
S = cumsum(X);
mask = logical(L);
% Lookup the cumulative value just before the start of each segment
isStart = mask & [true ; L(1:end-1) ~= L(2:end)];
startInds = find(isStart);
if startInds(1) == 1
    S_starts = [0 ; S(startInds(2:end)-1)];
else
    S_starts = S(startInds-1);
end
% Subtract off the excess values (i.e. the ones obtained above)
L_safe = cumsum(isStart); % we do this to main case the labels in L were not sorted integers
S(mask) = S(mask) - S_starts(L_safe(mask));
% Put NaNs in the false blocks
S(L==0) = NaN; 
end
0 Kommentare
  Quoc T. Phan
 am 19 Jun. 2020
        Hello
When it comes to work with group, these two functions are great tools. They go together
- findgroups: --> indexing groups
- splitapply: --> split your data by index, then apply @function to it, then combine back to original
Here is a sample code
clear
load patients
% Create a table X
X = table(LastName,Gender,Height,Weight,Age)
% Sort rows by Gender and Last Name (Actually u dont need Last Name, but I
% just put here in case)
X =  sortrows(X,{'Gender' 'LastName'},{'ascend' 'ascend'})
% Function 01: Using findgroups --> to return logical index
G = findgroups(X.Gender) 
% (*) Note: by default they index by alphabet order. Although 1st obs is male,
% however, F(emale) is before M(ale). Then 1 is Female and 2 is Male.
% Function 02: Using splitapply
% Basically what it does it slit table X by logical index G
% It then apply function cumsum for variable X.Height
cumHeight = splitapply(@(x1){cumsum(x1)},X.Height,G)
% Change cell to matrix and add to table X
X.cumHeight = cell2mat(cumHeight)
0 Kommentare
Siehe auch
Kategorien
				Mehr zu Operators and Elementary Operations finden Sie in Help Center und File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



