Search code examples
stringmatlabdoublecellcell-array

Multiply parts of cell array with factor in Matlab


I want to multiply parts of a cell array in Matlab (see example below).

my_cell1 = {'a', 'b', 'c'; 'd', '1', '2'; 'e', '3', '4'};
% Looks like:
% a b c
% d 1 2
% e 3 4
my_cell2 = my_cell1;
my_cell2(2:3, 2:3) = num2cell(str2double(my_cell2(2:3, 2:3)) * 2); %Multiply the numbers by factor 2
my_cell3 = {'a', 'b', 'c'; 'd', '2', '4'; 'e', '6', '8'};
isequal(my_cell2, my_cell3) %False

Apparently, my_cell2 is not equal to my_cell3. This seems to be the case because the numbers in my_cell2 are now doubles and not strings/characters anymore. However, when I try to use them as strings, I get an error:

my_cell2 = my_cell1;
my_cell2(2:3, 2:3) = num2str(str2double(my_cell2(2:3, 2:3)) * 2); %Error: Conversion to cell from char is not possible.

How can I multiply my_cell2 so that it becomes equal to my_cell3 at the end?


Solution

  • Add an intermediate step using cellfun to apply str2num to each of the cells in your (sub) cell array:

    my_cell1 = {'a', 'b', 'c'; 'd', '1', '2'; 'e', '3', '4'};
    
    my_cell2 = my_cell1;
    my_cell2(2:3, 2:3) = num2cell(str2double(my_cell2(2:3, 2:3)) * 2);
    my_cell2(2:3, 2:3) = cellfun(@(x) num2str(x), my_cell2(2:3, 2:3), 'UniformOutput', false);
    
    my_cell3 = {'a', 'b', 'c'; 'd', '2', '4'; 'e', '6', '8'};
    
    isequal(my_cell2, my_cell3) % true
    

    Since your initial "numerical" data is (also) represented as character arrays, you'll always need a proper conversion to numerical values. If your data would actually be numerical, this approach could be minimized:

    my_cell1 = {'a', 'b', 'c'; 'd', 1, 2; 'e', 3, 4};   % Note the difference here
    
    my_cell2 = my_cell1;
    my_cell2(2:3, 2:3) = cellfun(@(x) 2*x, my_cell2(2:3, 2:3), 'UniformOutput', false);
    
    my_cell3 = {'a', 'b', 'c'; 'd', 2, 4; 'e', 6, 8};   % Note the difference here
    
    isequal(my_cell2, my_cell3) % true
    

    I couldn't find a way to directly access and manipulate the values of the cell array in the corresponding range via my_cell2{2:3, 2:3}. Maybe, someone else has an idea on that.

    Hope that helps!


    Disclaimer: Tested with Octave 5.1.0, but also works in MATLAB Online.