Search code examples
matlabfor-loopcell-arraymatlab-table

How to make calculations on certain cells (within a table) that meet specific criteria?


I have the following code:

L_sum = zeros(height(ABC),1);
for i = 1:height(ABC)
     L_sum(i) = sum(ABC{i, ABC.L(i,4:281)});
 end

Here my table: enter image description here

Problem: My sum function sums the entire row values (col. 4-281) per date whereas I only want those cells to be added whose headers are in the cell array of ABC.L, for any given date.


X = ABC.L{1, 1}; gives (excerpt):

enter image description here


Red arrow: what sum function is referencing (L of same date).

Green arrow: what I am trying to reference now (L of previous date). enter image description here

Thanks for your help


Solution

  • To do that you need to first extract the columns you want to sum, and then sum them:

    % some arbitrary data:
    ABC = table;
    ABC.L{1,1} = {'aa','cc'};
    ABC.L{2,1} = {'aa','b'};
    ABC.L{3,1} = {'aa','d'};
    ABC.L{4,1} = {'b','d'};
    ABC{1:4,2:5} = magic(4);
    ABC.Properties.VariableNames(2:5) = {'aa','b','cc','d'}
    
    % summing the correct columns:
    L_sum = zeros(height(ABC),1);
    col_names = ABC.Properties.VariableNames; % just to make things shorter
    for k = 1:height(ABC)
        % the following 'cellfun' compares each column to the values in ABC.L{k},
        % and returns a cell array of the result for each of them, then
        % 'cell2mat' converts it to logical array, and 'any' combines the
        % results for all elements in ABC.L{k} to one logical vector:
        col_to_sum = any(cell2mat(...
            cellfun(@(x) strcmp(col_names,x),ABC.L{k},...
            'UniformOutput', false).'),1);
        % then a logical indexing is used to define the columns for summation:
        L_sum(k) = sum(ABC{k,col_to_sum});
    end