Atilla Ozgur
Atilla Ozgur

Reputation: 14701

Change string values to number in Matlab table

I am using Matlab2015b. And I would like to read a simple csv file to a table and change its string values to corresponding numeric values.

I have following example data.

Var1, VarClass
1 , attack
2 , normal
1, attack

I would like to change this string values to number. for example attack = 1, normal = -1.

My first try.

T = readtable('example_data.csv', 'Delimiter',',','FileType','text','TreatAsEmpty',{'?'});

rows_attack = strcmp(T(:,2),'attack');
T(rows_attack,2) = 1

rows_normal = strcmp(T(:,2),'normal');
T(rows_normal,2) = -1

I get following error:

Undefined function 'eq' for input arguments of type 'cell'.

What? Which undefined function? What is 'eq'?

Well. After reading some about table, I understood that supposedly higher level matlab does not override '=='. That is 'eq' which means equality. But error message certainly is not informative.

Then my second try.

T = readtable('example_data.csv', 'Delimiter',',','FileType','text','TreatAsEmpty',{'?'});


rows_attack = strcmp(T.VarClass,'attack');
T(rows_attack,2) = 1

This time, I get

Right hand side of an assignment into a table must be another table or a cell array.

Well. Okay. It wants table. I will give it one.

T = readtable('example_data.csv', 'Delimiter',',','FileType','text','TreatAsEmpty',{'?'});

rows_attack = strcmp(T.VarClass,'attack');
rows_attack_size = sum(rows_attack);
data_to_fill = ones(rows_attack_size,1) ;
T(rows_attack,2) = array2table(data_to_fill);

Well. This time error message is.

Conversion to cell from double is not possible.

I thought that this matlab table is similar to R data-frame or python pandas DataFrame. Well, certainly it is not. Can someone guide me about how to solve this problem?

Upvotes: 0

Views: 2539

Answers (2)

Atilla Ozgur
Atilla Ozgur

Reputation: 14701

Well. Thanks to @Yvon, I found my mistake and solved my problem. Following code works.

T = readtable('example_data.csv', 'Delimiter',',','FileType','text','TreatAsEmpty',{'?'});


 rows_attack = strcmp(T.VarClass,'attack');
 T.VarClass(rows_attack) = {-1};

 rows_normal = strcmp(T.VarClass,'normal');
 T.VarClass(rows_normal) = {1};

 T.VarClass = cell2mat(T.VarClass);

Upvotes: 0

Yvon
Yvon

Reputation: 2983

My Matlab gives different error message to your code.

>> rows_attack = strcmp(T(:,2),'attack')  

rows_attack =

     0

>> T(rows_attack,2) = 1
Right hand side of an assignment into a table must be another table or a cell array.
 >> T(rows_attack,2)

ans = 

   empty 0-by-1 table

The error is multi-fold. Applying strcmp on a table does not give a vector; instead it's a scalar 0. When indexing T with zero index it gives an empty table. If neither of these is a problem, then storing a scalar double into a table is a type-not-match.

I didn't get your error message Undefined function 'eq' for input arguments of type 'cell'. from any of my trial. Maybe your matlab environment or version has a different strcmp that has a different overload for tables.

Your second try is

>> rows_attack = strcmp(T.VarClass,'attack') 

rows_attack =

     1
     0
     1

>> T(rows_attack,2) = 1
Right hand side of an assignment into a table must be another table or a cell array.

>> T(rows_attack,2)    

ans = 

    VarClass
    ________

    'attack'
    'attack'

So this time the error is straightforward. Anyway, it looks like the desired is changing the first row to 1, since those are numbers. However, I got error

>> T(rows_attack,1) =2
Right hand side of an assignment into a table must be another table or a cell array.

Your last try works if respecting the above glitch in addressing the correct column.

>> rows_attack = strcmp(T.VarClass,'attack');
>> rows_attack_size = sum(rows_attack);
>> data_to_fill = ones(rows_attack_size,1) ;
>> T(rows_attack,2) = array2table(data_to_fill);
Conversion to cell from double is not possible.

>> data_to_fill

data_to_fill =

     1
     1

>> whos ans
  Name      Size            Bytes  Class    Attributes

  ans       2x1              1502  table              

>> T(rows_attack,1) = array2table(data_to_fill);
>> T

T = 

    Var1    VarClass
    ____    ________

    1       'attack'
    2       'normal'
    1       'attack'

>> 

Also, the following also works

>> rows_attack = strcmp(T.VarClass,'attack'); T.Var1(rows_attack) = -1

T = 

    Var1    VarClass
    ____    ________

    -1      'attack'
     2      'normal'
    -1      'attack'

Upvotes: 1

Related Questions