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

10 views (last 30 days)
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;
T.STATION(mask) = 'A';
mask = T.lat > 49.5 & T.lat < 50.5;
T.STATION(mask) = 'B';
mask = T.lat > 50.5 & T.lat < 51.5;
T.STATION(mask) = 'C';
mask = T.lat > 51.5 & T.lat < 52.5;
T.STATION(mask) = 'D';

Accepted Answer

dpb
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
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
Blue on 31 Jul 2019
My bad, nevermind.

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!