# How to conditionally assign characters for a new column in a table

5 views (last 30 days)
Blue on 31 Jul 2019
Edited: dpb on 31 Jul 2019
Hi,
Let's say that I have a simple table like so:
lat = [49, 50, 51, 52];
lat = lat'
lon = [-99, -100, -101, -102];
lon = lon'
T = table (lat, lon)
Now let's say that I wanted to add a station name based on the latitude in a new column 'station'. I could do like the code below but I am limited to using a single character as the station name (A, B, C or D) otherwise I get the following error: Unable to perform assignment because the size of the left side is 1-by-1 and the size of the right side is 1-by-9. Also, if I have a large number of stations I am going to have to add 2 lines for every stations which is clumsy. So. Is there a better way to do this (by better I mean a way that would diminish the number of lines required and allow multiple characters in the 'station' column) ?
mask = T.lat > 48.5 & T.lat < 49.5;
mask = T.lat > 49.5 & T.lat < 50.5;
mask = T.lat > 50.5 & T.lat < 51.5;
mask = T.lat > 51.5 & T.lat < 52.5;
##### 1 CommentShowHide None
Walter Roberson on 31 Jul 2019
T.STATION(mask) = {'Apple'} ;

dpb on 31 Jul 2019
Edited: dpb on 31 Jul 2019
Expanding a little on Walter's comment...
Lat = [49, 50, 51, 52].'; % create the right orientation in the first place...
Lon = [-99, -100, -101, -102].';
T = table(Lat,Lon); % and the base table
sta=categorical("Station "+string(['A':'D'].')); % make up names and they're rightly a categorical variable
[~,bin]=hist(T.Lat,1:4); % locate which one goes where..
T.Station=sta(bin); % and add to the table...
>> T
T =
4×3 table
Lat Lon Station
___ ____ _________
49 -99 Station A
50 -100 Station B
51 -101 Station C
52 -102 Station D
>>
NB: If don't have integer latitude invtervals; hist still will bin on the midpoints of the bins given...just use mod() to cast the bin number to the beginning of the array based on initial value...
[~,bin]=hist(T.Lat,unique(T.Lat));
T.Station=sta(mod(bin,49)+1);
NB2: I have a "syntactic sugar" utility routine I use when there is need for the test such as have written above
>> type iswithin
function flg=iswithin(x,lo,hi)
% returns T for values within range of input
% SYNTAX:
% [log] = iswithin(x,lo,hi)
% returns T for x between lo and hi values, inclusive
flg= (x>=lo) & (x<=hi);
>>
that's the version that is inclusive; there's another that passes a flag for which bound is/is not you'd want here. Just makes the higher-level code a little more succinct to be able to just return the logical vector as return from the function call...particularly if have multiple conditions.
NB3: Your bounds are exclusive on both ends so the x.5 values aren't included anywhere.

### More Answers (2)

Blue on 31 Jul 2019
Hi Walter. Your example does work but for some reason when I use it in real life it only applies the first station name and then throws back a 'Conversion to cell from char is not possible.' for all the other stations which is perplexing. Thoughts ?

Blue on 31 Jul 2019