Is there a simpler way to create an empty Table with a list of VariableNames?

I had to find a long long way around to solve this simple task.
optionsChange = cell2table(cell(0,9));
optionsChange.Properties.VariableNames{'Var1'}='Exp';
optionsChange.Properties.VariableNames{'Var2'}='Strike';
optionsChange.Properties.VariableNames{'Var3'}='Put_Mark';
optionsChange.Properties.VariableNames{'Var4'}='Put_Ask';
optionsChange.Properties.VariableNames{'Var5'}='Put_Bid';
optionsChange.Properties.VariableNames{'Var6'}='Put_Delta';
optionsChange.Properties.VariableNames{'Var7'}='Put_ImplVol';
optionsChange.Properties.VariableNames{'Var8'}='Date';
optionsChange.Properties.VariableNames{'Var9'}='DateNM';
Isn't there a nicer way to do it? Matlab really gets on my nerv after PHP and VBA

 Réponse acceptée

optionsChange = cell2table(cell(0,9), 'VariableNames', {'Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM'});

5 commentaires

optionsChange = cell2table(cell(0,9), VariableNames, {'Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM'});
I get this error
| Undefined function or variable 'VariableNames'.|
optionsChange = cell2table(cell(0,9), 'VariableNames', {'Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM'});
Steven
Steven le 21 Oct 2019
Modifié(e) : per isakson le 4 Juin 2021
This answer is poor quality
Sorry guys, but creating a table in matlab should be lot more simple.
First off why cant we create an empty table with column names?
"why cant we create an empty table with column names?"
@Gabor We can (now):
t = table([],{},'VariableNames',{'a','b'})
t = 0×2 empty table a b _ _

Connectez-vous pour commenter.

Plus de réponses (4)

Andrei, Walter's solution works, as would
optionsChange = array2table(zeros(0,9), 'VariableNames',{...});
or even
optionsChange = array2table(zeros(0,9));
optionsChange.Properties.VariableNames = {...};
(Both of those have the advantage that they create 0x1 variables in the table, rather than 0x0, and so if you subsequently do something like
>> optionsChange.Exp(2) = 2
optionsChange =
Exp Strike Put_Mark Put_Ask Put_Bid Put_Delta Put_ImplVol Date DateNM
___ ______ ________ _______ _______ _________ ___________ ____ ______
0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0
everything will grow in the vertical direction.)
BUT: based on your variable names, you may not end up what you're ultimately looking for. The problem is that "create an empty table" isn't really fully specified. It's kind of like saying, "create an empty variable". The question left unanswered is, what type of variables do you want in that table? The answer might be "all doubles", but it might not. The above all create nine double variables in the table, but your last two variable names indicate dates. If you're using datenums, you're fine (datenums are are just doubles, but if you want date strings, or datetimes, you'll have to either start out with the right thing, or overwrite the doubles in the table that you want to be dates. For example,
>> vnames = {'Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM'};
>> optionsChange = array2table(zeros(0,9), 'VariableNames',vnames);
>> optionsChange.Date = datetime(zeros(0,3)); % simple way to get a 0x1 datetime
>> optionsChange.DateNM = datetime(zeros(0,3));
>> summary(optionsChange)
Variables:
Exp: 0x1 double
Strike: 0x1 double
Put_Mark: 0x1 double
Put_Ask: 0x1 double
Put_Bid: 0x1 double
Put_Delta: 0x1 double
Put_ImplVol: 0x1 double
Date: 0x1 datetime
DateNM: 0x1 datetime
And finally, as is the case with any kind of variable in MATLAB, instead of creating an empty then growing it row by row, you might consider creating a table that's the right size but filled with NaNs and empty strings or whatever. For example,
optionsChange = array2table(nan(0,9));
That may be faster in the long run, because it doesn't have to keep reallocating memory as the table grows. That may or may not be useful or even possible in your case, just a suggestion.
Hope this helps.

5 commentaires

Thanks, Peter. Very informative answer. Let's go on further... Suppose, I created this table optionsChange and filled it with rows of data. Then later on I decided to add a new column (variable). If I do this like, Lets assume I didn't create the Date column from the beginning:
optionsChange.Date = datetime(zeros(0,3));
I get en error:
Error using .... (line 138)
To assign to or create a variable in a table, the number of rows must match the
height of the table.
The point is, do I always have to count the number of rows and create a new column with the same number of rows? It takes time and is very unproductive.
You might do one of two things. Starting from this table ...
>> optionsChange = array2table(rand(5,2))
optionsChange =
Var1 Var2
_______ _______
0.81472 0.09754
0.90579 0.2785
0.12699 0.54688
0.91338 0.95751
0.63236 0.96489
... you can add a new variable, but it has to be the correct height. You can get that height from the table you're assigning into:
>> optionsChange.Date = NaT(height(optionsChange),1)
optionsChange =
Var1 Var2 Date
_______ _______ ____
0.81472 0.09754 NaT
0.90579 0.2785 NaT
0.12699 0.54688 NaT
0.91338 0.95751 NaT
0.63236 0.96489 NaT
(By the way, it occurred to me that using the NaT function is a simpler way to preallocate a datetime than something like datetime(zeros(0,3))).
Or you can assign to a specific element of a new variable:
>> optionsChange = array2table(rand(5,2))
optionsChange =
Var1 Var2
________ ________
0.70605 0.82346
0.031833 0.69483
0.27692 0.3171
0.046171 0.95022
0.097132 0.034446
>> optionsChange.Date(5,1) = datetime('now')
optionsChange =
Var1 Var2 Date
________ ________ ____________________
0.70605 0.82346 NaT
0.031833 0.69483 NaT
0.27692 0.3171 NaT
0.046171 0.95022 NaT
0.097132 0.034446 25-Sep-2015 09:02:26
Notice the column number in Date(5,1): that's because Date does not exist and assigning to Date(5) would follow standard MATLAB behavior and create the 5th element of a row vector.
You can even assign off the end, and the other variables will gro, but you will get a warning about that.
>> optionsChange = array2table(rand(5,2));
>> optionsChange.Date(6,1) = datetime('now')
Warning: The assignment added rows to the table, but did not assign values to all of the table's existing variables. Those
variables have been extended with rows containing default values.
> In table/subsasgnDot (line 285)
In table/subsasgn (line 67)
optionsChange =
Var1 Var2 Date
_______ _______ ____________________
0.75127 0.95929 NaT
0.2551 0.54722 NaT
0.50596 0.13862 NaT
0.69908 0.14929 NaT
0.8909 0.25751 NaT
0 0 25-Sep-2015 09:03:21
Hope this helps.
Just wondering how you would round numbers in a table. I keep getting numbers like -5.2018e+05 but i want them rounded to whole integers (i.e. -520181)
Lachlan Noller: the easiest thing is to round the numbers before putting them in the table.
Also, they may already be rounded, and what you're seeing is just the shortg display. Perhaps just set your command window to use the longg format.

Connectez-vous pour commenter.

I know this is an old question but I usually do the following to initialise a new empty table:
% Make N by 2 matrix of fieldname + value type
variable_names_types = [["id", "double"]; ...
["x", "double"]; ...
["y", "double"]; ...
["time", "double"]; ...
["type", "string"]; ...
["description", "string"]];
% Make table using fieldnames & value types from above
my_table = table('Size',[0,size(variable_names_types,1)],...
'VariableNames', variable_names_types(:,1),...
'VariableTypes', variable_names_types(:,2));
I think this is quite readable and allows you to add value types.

4 commentaires

FYI the functionality you're using in your answer, the ability to specify 'Size' and 'VariableTypes' in the table constructor, was introduced in release R2018a which is why it wasn't suggested previously.
Ah I see, then my answer might be useful for people using later versions of matlab. Thanks for the addition!
this is useful for what I'm doing, but what should I use as variable type if I want let's say "x" to be an array of 2 double?
thanks
When individual entries are non-scalar, you have to use "cell" for the type, with the exception of "char".

Connectez-vous pour commenter.

Good solutions, everyone, but why isn't this functionality available through table? Usually, the data type conversion functions are used when you have already created data as one type and want to convert it to another. I don't see why this:
array2table(zeros(0,9), 'VariableNames',{...});
can't look like this:
table('VariableNames',{...});

10 commentaires

It can, as long as you specify the 'Size' name-value pair as well and you're using release R2018a or later. See Markus de Ruijter's answer.
Not exactly. That form requires you to redundantly enter the size information, which is already implied by the variable names.
The size is easily added using length(). But you need a type for each variable.
vnames = {'Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM'};
nv = length(vnames);
vt(1:nv) = "double";
t = table('Size', [0 nv], 'VariableNames', vnames, 'VariableTypes', vt)
t = 0×9 empty table
In Python (pandas), that's two lines.
vnames = ('Exp', 'Strike', 'Put_Mark', 'Put_Ask', 'Put_Bid', 'Put_Delta', 'Put_ImplVol', 'Date', 'DateNM')
t = pd.DataFrame(columns=vnames, dtype='float')
I agree with Ilya Gurin, it would be much easier to be able to initialise tables with this syntax:
table('VariableNames',{...});
which i would expect to return an empty table with named variables.
That form requires you to redundantly enter the size information, which is already implied by the variable names.
The number of variables is implied by the variable names. The number of rows is not, and that is what you specify when you specify the 'Size'. That also gives a sanity check -- if you say you want a 5-by-6 table with 5 variables MATLAB can note the mismatch and ask you to make a 5-by-5 table or specify 6 variable names.
Point taken about the number of rows. But Peter Perkins' answer back in 2015 explicitly specifies zero rows. This is often convenient when performance is not critical. (And I suspect that tables are a poor choice for performance-critical data structures, anyway.)
Ilya Gurin
Ilya Gurin le 3 Juin 2021
Modifié(e) : Ilya Gurin le 3 Juin 2021
I don't accept the point about a "sanity check." That's otherwise known as redundancy, and I think it's poor programming practice. If I want to make a table, I think to myself, "I want columns foo, bar, and baz," not "I want three columns, and their names will be foo, bar, and baz." And then if I want to add another column, I have to remember that there are two things that need to change, otherwise Matlab will give me a runtime error.
P.S: Walter Roberson's comment two weeks ago determines the number of columns automatically using length, which defeats the purpose of a sanity check.
I don't accept the point about a "sanity check."
Then you should be using a different programming language. MATLAB is full of sanity checks. MATLAB is specifically designed for people who are not expert programmers: people who cannot be counted upon to only work with values that are "sane" from the point of view of the programming language. People who do not use good programming practices themselves.
In context, putting in sanity checks to detect problems early is good programming practice, for what MATLAB is intended for. MATLAB's goal of efficiency is secondary to MATLAB's goal to make the software accessible to users who are to be expected to make a lot of mistakes.
1) I'm all for certain kinds of sanity checks. I've spent hours fixing Code Analyzer ("m-lint") warnings, in my own code and especially other people's code. I just don't think the particular feature of requiring a Size argument when creating a table is a useful sanity check. And, in fact, your own code sample defeats such sanity-checking as may exist.
2) If the goal is to make software accessible to non-experts who make a lot of mistakes, I posit that requiring a Size parameter and a list of VariableNames that can get out of sync is contrary to that goal.

Connectez-vous pour commenter.

Mathworks, please allow
tbl = table("VariableNames", ["var1" "var2"....]);
and avoid ugly hacks like array2table(zeros(0... or cell2table(cell(0,....)

3 commentaires

Please submit this enhancement request to Technical Support directly using the Contact Support link under the Get Support heading at the end of this page.
As discussed in https://www.mathworks.com/matlabcentral/answers/244084-is-there-a-simpler-way-to-create-an-empty-table-with-a-list-of-variablenames#answer_422250 you can already table() indicating varible names, table size, and variable types, without needing to convert zeros() or cell()
Dan
Dan le 17 Fév 2025
Modifié(e) : Dan le 17 Fév 2025
MATLAB precludes creating a table with just variable names to preclude the need for subsequent dynamic resizing of the table. If MATLAB allows:
tbl = table("VariableNames", ["var1","var2"]);
and makes the assumption that you want your data to be of type double, the next think you'll want to do is this:
tbl.var1 = ["a","b","sdf"]';
which MATLAB does not allow either as it would require the resizing of all the other variables in the table simultaneously as well as retyping the variable var1. Very expensive. This is allowed with a structure but there is no enforcing that the number of parameters is the same for all the other fields. With a structure, you could go with a nonscalar structure to enforce sameness for number of elelments across all fields, but there is a lot of overhead associated with resizing for that too. Maybe one of the reasons that MATLAB made tables was to enforce better efficiency than you'd get with structures?
Bottom line ... you have to go through all the work to generate the data that is going to populate your table, either before or after creating the table. MATLAB wants you to do it in advance to reduce overhead associated with resizing and retyping.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Startup and Shutdown dans Centre d'aide et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by