2

In Excel you can use the "filter" function to find certain words in your columns. I want to do this in Matlab over the entire table.

Using the Matlab example-table "patients.dat" as example; my first idea was to use:

patients.Gender=={'Female'}

which does not work.

strcmp(patients.Gender,{'Female'})

workd only in one column ("Gender").

My problem: I have a table with different words say 'A','B','bananas','apples',.... spread out in an arbitrary manner in the columns of the table. I only want the rows that contain, say, 'A' and 'B'.

It is strange I did not find this in matlab "help" because it seems basic. I looked in stackedO but did not find an answer there either.

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
Erik
  • 71
  • 2
  • 12
  • Definitely use `regexp` as what @Benoit_11 suggested. `strcmp` will only let you compare with one string at a time. However, you can use `strcmp` if you loop over all of your columns in your table and make a cell array where each cell would retrieve the rows of each column that match what you're finding. – rayryeng Feb 11 '15 at 20:38
  • I realize that I can use a for loop that browses a row at a time using the strcmp examlpe stated in the question. – Erik Feb 11 '15 at 20:42
  • rayryeng, I cannot find the @Benoit_11 example you mentioned. – Erik Feb 11 '15 at 20:50
  • It looks like he removed his comment, but it was pretty inconsequential. He simply asked if you tried using `strcmp` or `regexp`. – rayryeng Feb 11 '15 at 20:52
  • Okay : ) My problem is not that I cannot program a solution (like using a for loop). My problem is that I am extremly frustrated that I cannot find a good way to do this. I simply want to filter a table on words. In excel this would be simple. And in matlab? Even simpler?? – Erik Feb 11 '15 at 20:58
  • Yes sorry I removed it because I saw after posting it that you tried `strcmp` already. I should have left the part about `regexp` though :P – Benoit_11 Feb 11 '15 at 22:27
  • I think a simple way would be to use `table2cell` to get a cell from your table, then `regexp` to find occurences of particular words. `regexp` works well on cell arrays. If you need help for this please ask! – Benoit_11 Feb 11 '15 at 22:38

2 Answers2

1

A table in Matlab can be seen as an extended cell array. For example it additionally allows to name columns.

However in your case you want to search in the whole cell array and do not care for any extra functionality of a table. Therefore convert it with table2cell.

Then you want to search for certain words. You could use a regexp but in the examples you mention strcmp also is sufficient. Both work right away on cell arrays.

Finally you only need to find the rows of the logical search matrix.

Here the example that gets you the rows of all patients that are 'Male' and in 'Excellent' conditions from the Matlab example data set:

patients = readtable('patients.dat');
patients_as_cellarray = table2cell(patients);
rows_male = any(strcmp(patients_as_cellarray, 'Male'), 2); % is 'Male' on any column for a specific row
rows_excellent = any(strcmp(patients_as_cellarray, 'Excellent'), 2); % is 'Excellent' on any column for a specific row
rows = rows_male & rows_excellent; % logical combination
patients(rows, :)

which indeed prints out only male patients in excellent condition.

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
  • So it seems that the table format is not actually that good to use in my case. The reason I wanted to use the table format in the first place was to make the coding and data management more convenient.
    Now I solved the problem by using _eval_ in a loop and rearranging the table so that I can look into it columns-wise.
    `For i=1:endCol Place(:,i)=eval([‘strcmp(mytable.Val’,num2str(i),’stringToCompare’]); End` As you mention, it may be easier to use **regexp** over the entire cell-transformed table instead. I will try that!
    – Erik Feb 12 '15 at 22:16
  • PS. I used the stackEdit-Editor to make the comment above (it looked fine there...) but is not okay here. Sorry. – Erik Feb 12 '15 at 22:18
1

Here is a simpler, more elegant syntax for you:

matches = ((patients.Gender =='Female') & (patients.Age > 26));
subtable_of_matches = patients(matches,:);

% alternatively, you can select only the columns you want to appear,
% and their order, in the new subtable.
subtable_of_matches = patients(matches,{'Name','Age','Special_Data'});

Please note that in this example, you need to make sure that patients.Gender is a categorical type. You can use categorical(variable) to convert the variable to a categorical, and reassign it to the table variable like so:

patients.Gender = categorical(patiens.Gender);

Here is a reference for you: https://www.mathworks.com/matlabcentral/answers/339274-how-to-filter-data-from-table-using-multiple-strings

Matt
  • 161
  • 2
  • 12