# How to lookup and return a corresponding value from table?

50 views (last 30 days)
deepak kumar on 27 Dec 2021
Commented: deepak kumar on 28 Dec 2021
I have a table the first column of which contains a string and other columns contain numeric data, how do I match the string and return the corresponding values form other columns for this string. Lets say for 'obs2' I want '2' as output. I am using following code but this isn't working.
cmnt0 = {'obs1';'obs2';'obs3';'obs4'};
curve=[1;2;3;2];
cmnt1 = table(cmnt0,curve,'VariableNames',{'obs','Curve'})
cmnt1 = 4×2 table
obs Curve ________ _____ {'obs1'} 1 {'obs2'} 2 {'obs3'} 3 {'obs4'} 2
for i=[1,2,3,4]
x=strcmp(cmnt1(i,1),'obs1')
if x==1
%% some code here after that
end
end
x = logical
0
x = logical
0
x = logical
0
x = logical
0

_ on 27 Dec 2021
Edited: _ on 27 Dec 2021
It isn't working because cmnt1(i,1) is a sub-table of the table cmnt1 that contains one cell of cmnt1. You want to refer to the contents of the cell directly, so use curly brace indexing:
cmnt0 = {'obs1';'obs2';'obs3';'obs4'};
curve=[1;2;3;2];
cmnt1 = table(cmnt0,curve,'VariableNames',{'obs','Curve'})
cmnt1 = 4×2 table
obs Curve ________ _____ {'obs1'} 1 {'obs2'} 2 {'obs3'} 3 {'obs4'} 2
% introduce a third column for demonstration:
cmnt1.Curve_2 = [5;6;7;8]
cmnt1 = 4×3 table
obs Curve Curve_2 ________ _____ _______ {'obs1'} 1 5 {'obs2'} 2 6 {'obs3'} 3 7 {'obs4'} 2 8
for i=[1,2,3,4]
% x=strcmp(cmnt1(i,1),'obs1')
x=strcmp(cmnt1{i,1},'obs1')
if x==1
%% some code here after that
output = cmnt1{i,2:end} % do this to store the contents of the cells in columns 2 to the end (which are all numeric), or
output = cmnt1{i,2} % do this to store the contents of the cell in column 2
end
end
x = logical
1
output = 1×2
1 5
output = 1
x = logical
0
x = logical
0
x = logical
0
You can do the same thing without a loop, using logical indexing, which is intended to also handle the situation where the string you are matching occurs more than once in the first column of the table:
% introduce a second 'obs1':
cmnt1{3,1} = {'obs1'}
cmnt1 = 4×3 table
obs Curve Curve_2 ________ _____ _______ {'obs1'} 1 5 {'obs2'} 2 6 {'obs1'} 3 7 {'obs4'} 2 8
is_match = strcmp(cmnt1{:,1},'obs1')
is_match = 4×1 logical array
1 0 1 0
output_array = cmnt1{is_match,2:end}
output_array = 2×2
1 5 3 7
output_subtable = cmnt1(is_match,2:end)
output_subtable = 2×2 table
Curve Curve_2 _____ _______ 1 5 3 7
deepak kumar on 28 Dec 2021
But containers.Map are the exact thing I was looking for.

dpb on 27 Dec 2021
I'd start by turning 'obs' into a categorical variable...
cmnt0 = categorical({'obs1';'obs2';'obs3';'obs4'});
curve=[1;2;3;2];
tC = table(cmnt0,curve,'VariableNames',{'Obs','Curve'});
...
C=t.Curve(t.Obs=='Obs1');
Alternatively, if there is some reason to not create the categorical variable, then
C=t.Curve(contains(t.Obs,{'Obs1'}));
With such a data set, I'd suggest you'll find that groupsummary and/or rowfun and friends with grouping variables will solve virtually all such problems almost automagically.
dpb on 27 Dec 2021
" avoid CONTAINS..."
Good point...why I would use categorical variables here.