Inserting additional data in an already created table

Hello, Im messing around with tables again and create one from the user inputs from inputdlg
prompt = {'Soak(s)','Soak Move (ymm)','Laser Volts (Soak, Image)','numImages(afterSOAK)','ZTLpos(soak), abs','Back To Nominal Wait Time(s)','NumImages (Back To Nominal)'};
dlgtitle = 'Laser Soak';
dims = [1 35];
definput = {'30','-1','2, 0.18','4','-1833','60','12'};
answer = inputdlg(prompt,dlgtitle,dims,definput);
answer
T = table(char(answer))
I want to add another entry to the end and thought this would do it
defaultZTL='-2000';
T(end+1,1)={defaultZTL}
But Im getting this error
Assigning to a character variable in a table is only supported when the right-hand side value is a table. Consider using a string
variable in the table for text data.
Error in HTS_TestSoftware/LaserSOAKButtonPushed (line 12557)
T(end+1,1)={defaultZTL}

1 Comment

I've also tried to create a new table for the additonal row
T = table(char(answer))
rnames={'Soak(s)','Soak Rel. Pos (mm)','Soak/Image Laser (V)',['#Fast Images(PostSoak) @ ',num2str(afterSoakPause),'s'],'ZTL (Soak)','Return To Nom(ztl). Wait(s)','#Images(Return To Nom ztl)'}'
T.Properties.RowNames=rnames
T.Properties.VariableNames={'Input'};
% Add new row by creating another table
defaultZTL='-2000';
Tnew = table(defaultZTL,'RowNames',{'ZTL default Pos'}) ;
T = [T ; Tnew]
Incorrect number of arguments.
Error in HTS_TestSoftware/LaserSOAKButtonPushed (line 12564)
Tnew = table(defaultZTL,'RowNames',{'ZTL default Pos'}) ;

Sign in to comment.

 Accepted Answer

The issue is that char arrays must be padded so that they all have the same length. The value you are assigning does not have the same width as the other values in the table.
The simplest solution is to use strings instead.
answer = {'30','-1','2, 0.18','4','-1833','60','12'}';
T = table(string(answer))
T = 7x1 table
Var1 _________ "30" "-1" "2, 0.18" "4" "-1833" "60" "12"
defaultZTL = '-2000';
T(end+1,1) = {defaultZTL}
T = 8x1 table
Var1 _________ "30" "-1" "2, 0.18" "4" "-1833" "60" "12" "-2000"

7 Comments

"The issue is that char arrays must be padded so that they all have the same length. The value you are assigning does not have the same width as the other values in the table."
Even if they are the same length this allocation fails:
T = table(['hello';'world'])
T = 2x1 table
Var1 _____ hello world
T{end+1,1} = 'one!!' % allocating the content works
T = 3x1 table
Var1 _____ hello world one!!
T(end+1,1) = {'two!!'} % allocating a cell array fails
Error using () (line 113)
Assigning to a character variable in a table is only supported when the right-hand side value is a table. Consider using a string variable in the table for text data.
Good call. I was getting width errors at some point in my debugging and didn't fully troubleshoot.
  • Using curly braces indexes a table as an array. What is assigned has to match the data type of the array.
  • Using parentheses indexes the table as a table. What is assigned must be a table.
T{end+1,1} = 'one!!' works because the left and right side are char arrays of width 5
T{end+1,1} = 'one' doesn't work because the left side is a char arrays of width 5 and the right side is a char array of width 3
T{end+1,1} = {'two!!'} doesn't work because the left side in a char array and the right is a cell array.
T(end+1,1) = {'two!!'} doesn't work because the left side in a table and the right is a cell array.
The string datatype is more flexible than char. The following commands all work if the table variable type is string
T = table(["hello";"world"]);
T(end+1,1) = {'two!!'}
T = 3x1 table
Var1 _______ "hello" "world" "two!!"
T{end+1,1} = {'two!!'}
T = 4x1 table
Var1 _______ "hello" "world" "two!!" "two!!"
T(end+1,1) = {"two!!"}
T = 5x1 table
Var1 _______ "hello" "world" "two!!" "two!!" "two!!"
T{end+1,1} = "two"
T = 6x1 table
Var1 _______ "hello" "world" "two!!" "two!!" "two!!" "two"
T.Var1(end+1) = "two"
T = 7x1 table
Var1 _______ "hello" "world" "two!!" "two!!" "two!!" "two" "two"
T.Var1{end+1} = 'two'
T = 8x1 table
Var1 _______ "hello" "world" "two!!" "two!!" "two!!" "two" "two" "two"
"T(end+1,1) = {'two!!'} doesn't work because the left side in a table and the right is a cell array."
Yet the documentation states that this exact case should work, it is one of the two recommended ways to allocate an entire row to a table:
states "To assign one row to a table, you can use either a one-row table or a cell array. In this case, using a cell array can be more convenient than creating and assigning a one-row table."
Lets see if it works for non-column numeric matrices:
T = table([1,2;3,4])
T = 2x1 table
Var1 ______ 1 2 3 4
T{end+1,1} = [5,6]
T = 3x1 table
Var1 ______ 1 2 3 4 5 6
T(end+1,1) = {[7,8]} % !!!!
T = 4x1 table
Var1 ______ 1 2 3 4 5 6 7 8
So there really is some special case for character matrices.
I noticed that the example accompanying that statement uses strings, in which case this sytnax does work.
T = table(["hello";"world"]);
T(end+1,1) = {"two!!"}
T = 3x1 table
Var1 _______ "hello" "world" "two!!"
I don't have enough insight to know why it is different for char arrays. The only explanation I can offer is the one given in the error message: "Assigning to a character variable in a table is only supported when the right-hand side value is a table."
Thankyou Chris using "string" did work. I have to say I do love the table output format, but do find tables a real pain to work with!
So I used 2 approaches:
1:
T(end+1,1) = {defaultZTL}
2:
Tnew = table(string(defaultZTL),'VariableNames',{'Input'},'RowNames',{'ZTL default Pos'})
T = [T ; Tnew]
The output is below. Using method 1, how would I also include the row name?
T =
9×1 table
Input
_________
Soak(s) "30"
Soak Rel. Pos (mm) "-1"
Soak/Image Laser (V) "2, 0.18"
#Fast Images(PostSoak) @ 0.5s "4"
ZTL (Soak) "-1833"
Return To Nom(ztl). Wait(s) "60"
#Images(Return To Nom ztl) "12"
Row8 "-2000"
ZTL default Pos "-2000"
Say this is your table
T = table(["30";"-1"],'RowNames',{'Soak(s)';'Soak Rel.'})
T = 2x1 table
Var1 ____ Soak(s) "30" Soak Rel. "-1"
and you add the new row
T(end+1,1) = {"2, 0.18"}
T = 3x1 table
Var1 _________ Soak(s) "30" Soak Rel. "-1" Row3 "2, 0.18"
then you can set the new row name
T.Properties.RowNames{end} = 'new name'
T = 3x1 table
Var1 _________ Soak(s) "30" Soak Rel. "-1" new name "2, 0.18"
To add to Voss' response, rownames are stored in the table metadata. They are accessed through the table properties. I don't think you can update rownames when using a cell array to add a table row
Another option that would work is to add the names as a 2nd table column. Then you can update both while using the cell array approach.
input = string({'30','-1','2, 0.18','4','-1833','60','12'})';
rnames=string({'Soak(s)','Soak Rel. Pos (mm)','Soak/Image Laser (V)','#Fast Images(PostSoak) @ 0.5s','ZTL (Soak)','Return To Nom(ztl). Wait(s)','#Images(Return To Nom ztl)'})';
T = table(rnames,input)
T = 7x2 table
rnames input _______________________________ _________ "Soak(s)" "30" "Soak Rel. Pos (mm)" "-1" "Soak/Image Laser (V)" "2, 0.18" "#Fast Images(PostSoak) @ 0.5s" "4" "ZTL (Soak)" "-1833" "Return To Nom(ztl). Wait(s)" "60" "#Images(Return To Nom ztl)" "12"
defaultZTL = '-2000';
T(end+1,:) = {'defaultZTL',defaultZTL}
T = 8x2 table
rnames input _______________________________ _________ "Soak(s)" "30" "Soak Rel. Pos (mm)" "-1" "Soak/Image Laser (V)" "2, 0.18" "#Fast Images(PostSoak) @ 0.5s" "4" "ZTL (Soak)" "-1833" "Return To Nom(ztl). Wait(s)" "60" "#Images(Return To Nom ztl)" "12" "defaultZTL" "-2000"

Sign in to comment.

More Answers (1)

Try the function made for adding columns to tables: addvars

Categories

Products

Release

R2024b

Tags

Community Treasure Hunt

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

Start Hunting!