If else -statement doesn't work

I am trying to create a new column to a table with a value depending on the result on previous column. I am a beginner with MatLab (and coding) and have tried to fix the problem (using documentation, answers, YouTube and Google), but can't just figure where the problem is, which is probably something very simple (and me making a amateur mistake).
Here is the code, first two lines creating a table and summarizing the columns.
taAct= array2table(randi([0 30],8,3)); %making a table as my final dataset is as table
taAct.Sum = sum(taAct.Variables,2)
if taAct.Sum >= 60
taAct.actClass = 3;
elseif taAct.Sum >= 40
taAct.actClass = 2;
elseif taAct.Sum >= 30
taAct.actClass = 1;
else
taAct.actClass = 0
end
The problem is that it gives an error: "To assign to or create a variable in a table, the number of rows must match the height of the table".
I also tried to add the column first only with zeros, before the if-statement:
NewV = zeros(8,1)
taAct.actClass = NewV
But that didn't help either, still the same error.
I even tried to execute this with an array, but still the last column stays empty. So, please be kind and point me out, where the mistake is. I know how to do this with indeces, but with multiple steps, so I would love to learn how to do this more efficiently and correctly.

1 Comment

Ps. I wan't to thank for all the solutions and I now know multiple ways to execute this. But I still don't know what was wrong with the original if-statement and why it did not work. I would be very eager to learn from my mistake to avoid similar ones in the future. So if someone would be up to shortly explain the reason, I would be very grateful!

Sign in to comment.

 Accepted Answer

Actually you can do this in just one line using MATLAB discretize
taAct.actClass = discretize(taAct.Sum,[0,30,40,60,inf]) - 1

3 Comments

Or if the classes aren't consecutive integers (and so the -1 technique wouldn't work) you could use the third (or third and fourth) input for discretize.
taAct= array2table(randi([0 30],8,3)); %making a table as my final dataset is as table
taAct.Sum = sum(taAct.Variables,2)
taAct = 8×4 table
Var1 Var2 Var3 Sum ____ ____ ____ ___ 12 2 17 31 4 13 24 41 4 16 10 30 0 4 2 6 10 15 26 51 8 6 30 44 26 30 18 74 5 18 9 32
taAct.actClass = discretize(taAct.Sum,[0,30,40,60,inf], ...
'categorical', ["small", "medium", "large", "huge"])
taAct = 8×5 table
Var1 Var2 Var3 Sum actClass ____ ____ ____ ___ ________ 12 2 17 31 medium 4 13 24 41 large 4 16 10 30 medium 0 4 2 6 small 10 15 26 51 large 8 6 30 44 large 26 30 18 74 huge 5 18 9 32 medium
taAct.Price = discretize(taAct.Sum,[0,30,40,60,inf], [1.99, 3.49, 4.89, 6.39])
taAct = 8×6 table
Var1 Var2 Var3 Sum actClass Price ____ ____ ____ ___ ________ _____ 12 2 17 31 medium 3.49 4 13 24 41 large 4.89 4 16 10 30 medium 3.49 0 4 2 6 small 1.99 10 15 26 51 large 4.89 8 6 30 44 large 4.89 26 30 18 74 huge 6.39 5 18 9 32 medium 3.49
taAct(taAct.actClass == "huge", :)
ans = 1×6 table
Var1 Var2 Var3 Sum actClass Price ____ ____ ____ ___ ________ _____ 26 30 18 74 huge 6.39
Cool! I am so overwhelmed with all the coding and functions etc. in MatLab and it is so cool when someone is talented with these! I have been trying to build my own code and function to run my analyses with it, and I know there are some many parts which are made with "amateur"-mode, meaning multiple lines of code :D. But as long as it works, everything is good, right ;)? But constantly eager to learn more! Thank you very much for this simple solution!
Your welcome. For this particular situation it is nice that there is some built in functionality. The approaches given in other answers, showing you how to use the logical indexing, are very instructive though and really worth understanding as they can be applied for many more general situations.

Sign in to comment.

More Answers (2)

Initialize the table:
taAct= array2table(randi([0 30],8,3)); %making a table as my final dataset is as table
taAct.Sum = sum(taAct.Variables,2)
taAct = 8×4 table
Var1 Var2 Var3 Sum ____ ____ ____ ___ 12 16 17 45 25 5 30 60 7 19 30 56 29 25 21 75 2 17 5 24 0 19 27 46 15 17 29 61 5 27 5 37
Add a new column, actClass:
NewV = zeros(8,1);
taAct.actClass = NewV
taAct = 8×5 table
Var1 Var2 Var3 Sum actClass ____ ____ ____ ___ ________ 12 16 17 45 0 25 5 30 60 0 7 19 30 56 0 29 25 21 75 0 2 17 5 24 0 0 19 27 46 0 15 17 29 61 0 5 27 5 37 0
Use logical indexing to set the value of actClass in more than one row at a time:
idx = taAct.Sum >= 60;
taAct.actClass(idx) = 3;
idx = taAct.Sum < 60 & taAct.Sum >= 40;
taAct.actClass(idx) = 2;
idx = taAct.Sum < 40 & taAct.Sum >= 30;
taAct.actClass(idx) = 1;
% idx = taAct.Sum < 30; % this one's not necessary since
% taAct.actClass(idx) = 0; % actClass is 0 by default
disp(taAct);
Var1 Var2 Var3 Sum actClass ____ ____ ____ ___ ________ 12 16 17 45 2 25 5 30 60 3 7 19 30 56 2 29 25 21 75 3 2 17 5 24 0 0 19 27 46 2 15 17 29 61 3 5 27 5 37 1
A more compact way to write the same commands:
taAct.actClass(taAct.Sum >= 60) = 3;
taAct.actClass(taAct.Sum < 60 & taAct.Sum >= 40) = 2;
taAct.actClass(taAct.Sum < 40 & taAct.Sum >= 30) = 1;

2 Comments

Thank you for your help, this helped a lot!
You're welcome!

Sign in to comment.

The easiest method will be to first create a zero array, and then fill in the values according to the required logic:
% intialize
taAct= array2table(randi([0 30],8,3));
taAct.Sum = sum(taAct.Variables,2);
taAct.actClass = zeros(size(taAct.Sum));
% first assign the values where the sum is larger then 30
taAct.actClass( taAct.Sum >= 30 ) = 1;
% now assign the values for 40
taAct.actClass( taAct.Sum >= 40 ) = 2;
% finally for the values larger then 60
taAct.actClass( taAct.Sum >= 60 ) = 3;
% show resulting table
taAct
taAct = 8×5 table
Var1 Var2 Var3 Sum actClass ____ ____ ____ ___ ________ 2 30 2 34 1 27 23 24 74 3 26 13 1 40 2 4 5 8 17 0 0 2 18 20 0 17 8 30 55 2 10 22 30 62 3 26 6 4 36 1

2 Comments

Thank you for your help, this helped a lot, and actually the code is even more simpler than above (which I already had accepted and I don't know what is the "correct and most polite" way to handle the "Accept answer"). Very helpful and learned also few other tricks!
Jon
Jon on 8 Jul 2022
Edited: Jon on 8 Jul 2022
You can unaccept an answer, and then select as reason, found better answer. I don't think it is impolite, and is useful as it help sort the answers for others who might have the same problem.

Sign in to comment.

Products

Release

R2022a

Asked:

on 8 Jul 2022

Commented:

Jon
on 8 Jul 2022

Community Treasure Hunt

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

Start Hunting!