Search code examples
arraysalgorithmmatlabcell-array

Take array that shows values with numbers of times they appear, make array that lists values individually


I have an array that looks like:

20  1
20  7
45  3
127 17
102 1
90  1
64  1

etc... where the left-hand column shows a light intensity value and the right-hand column shows the number of times it appears. I want a corresponding cell array that expands the array and lists each value, individually, for the number of times it appears. Like so (ignore the left-hand cell column):

[]  20
[]  20
[]  20
[]  20
[]  20
[]  20
[]  20
[]  20
[]  45
[]  45
[]  45

etc... Who can tell me a CLEVER way of doing this? Tricky indexing here. I have the following clunky piece that (kind of) works:

% Determine the number of 10-minute intervals for which a light level is
% recorded (sum all the unique light levels and their repeats).  
no_light_levels = sum(repeat_arr(:, 2));
%
% 'geologger_data_all' records time of each light level reading and the
% light level.  
geologger_data_all{no_light_levels, 2} = []; 
geologger_data_all(1, 2) = {repeat_arr(1, 1)};
% 
k_out = 2;                                  % index for out arr.
for k = 2:length(repeat_arr)
    light_level = repeat_arr(k, 1);         % grab the light level
    appears = repeat_arr(k, 2);             % does it repeat?
    if appears == 1
        geologger_data_all(k_out, 2) = {light_level};   % record
        k_out = k_out + 1; 
    elseif appears > 1
        % Record the light level for the number of times it appears.  
        geologger_data_all(k_out:(k_out + appears - 1), 2) = {light_level};
        k_out = k_out + appears;            % advance index for out arr.  
    end
end
%

Where repeat_arr looks like the first formatted array shown here. Thanks in advance for any tips.


Solution

  • What you have is essentially run-length-encoded data which you can decode with repelem which repeats each element the specified number of times

    data = [20 1;20 7;45 3;127 17;102 1;90 1;64 1];
    out = repelem(data(:,1), data(:,2))
    

    If you actually need to make this a cell array like you've shown you can add the following step:

    result(:,2) = num2cell(out);
    

    If you are using a version of MATLAB older than R2015a (before repelem was introduced) you can use the solution provided here to get similar functionality.