MATLAB: How to set table VariableNames from a cell

csvexcelmachine learningtablevariablenames

I have a peculiar frustrating situation: am trying to set the headers of a 1×19 table from an excel table to provide as an input to a Machine learning struct. As per the documentation of the struct i need to provide a MATLAB Table with 19 rows of numeric data with the following headers.
gender seniorcitizen partner dependents tenure phoneservice multiplelines internetservice onlinesecurity onlinebackup deviceprotection techsupport streamingtv streamingmovies contract paperlessbilling paymentmethod monthlycharges totalcharges
10 0 200 200 16 100 200 200 300 300 300 300 300 300 502 200 630 18.95 326.8
However, the problem is, for some reason, i get the dreaded, unintelligible error message:
Function 'subsindex' is not defined for values of class 'table'.
1. I tried importing the excel as a variable using the import facility. Does not work. 2. I tried creating the table from a cell array of headers using the cell2table. That gives another of the infamous cryptic errors. (seriously, wonder who writes those error messages in MATLAB? they seem to have a special training for making it as unfriendly as possible)
I found that the Properties of the table in MATLAB workspace look like below:
description: ''
userdata: []
dimensionnames: {'row' 'variables'}
variablenames: {1×19 cell}
variabledescriptions: {}
variableunits: {}
rownames: {}
I need to set the VariableNames directly as values instead of a 1×19 cell. How do i do it? (And pls avoid referring me to MATLAB table documentation. Does not work)

Best Answer

OK, there was enough of a hint that you used Regression Learner App. I'd never even opened it before, but since you used "Churn" in the model name and had the list of variables, I was able to build a model.
Let's see if can predict something; I just called the exported model TM for brevity--
>> TM.predictFcn(T(1:3,:)) % predict first three values from existing table
ans =
200.0000
200.0000
155.5556
>>
The easiest way to use the model is something like, presuming the original table is T
TT=T(1:3,:); % just make a copy of the first three rows; gives the variables as exist
TT.SeniorCitizen=ones(3,1); % let's change a variable to something different...
>> TM.predictFcn(TT) % and see what we now predict for those...
ans =
100.0000
200.0000
111.1111
>>
So, did make a difference in prediction for two of the three; not sure w/o more in-depth digging as to why the second is the same but seems to work as advertised.
Not sure just what you actually tried to do; perhaps building a table that doesn't match the original but only includes the predictors doesn't work??? I dunno, didn't try it.
Again, show just the exact code you tried in sequence without any effort to analyze that we can see and can probably tell where that went wrong, too.
ADDENDUM
To create a new table that just has the required variables in it, use the facility of table addressing...
>> Tpred=T(1:3,TM.RequiredVariables); % just three rows for brevity
Tpred =
3×19 table
gender SeniorCitizen Partner Dependents tenure PhoneService MultipleLines InternetService OnlineSecurity OnlineBackup DeviceProtection TechSupport StreamingTV StreamingMovies Contract PaperlessBilling PaymentMethod MonthlyCharges TotalCharges
______ _____________ _______ __________ ______ ____________ _____________ _______________ ______________ ____________ ________________ ___________ ___________ _______________ ________ ________________ _____________ ______________ ____________
20 0 100 200 1 200 700 400 200 100 200 200 200 200 500 100 600 29.85 29.85
10 0 200 200 34 100 200 400 100 200 100 200 200 200 501 200 610 56.95 1889.5
10 0 200 200 2 100 200 400 100 100 200 200 200 200 500 100 610 53.85 108.15
>>
As this shows, the cell array of names is just fine for addressing variables. I don't know where you came up against the categorical problem unless you had converted some of the input table variables to categorical earlier before importing into the App.
BTW, this is also OK for predicting with; the model object clearly matches variable names in the table; I'd venture undoubtedly one could have other variables added as well as long as the originals are there and have the correct data types as were extant when the model was fitted.
table addressing is extremely flexible but have to get the syntax right for what are trying to do; the detailed info is at Access-data-in-a-table
ADDENDUM SECOND
BTW, if you were to want or need to do so, you can build a new table from scratch with the required variables with table; if the data are in variables of the desired name, those will be the default names, otherwise the optional 'VariableNames' property will accept the cell array or you can redefine the names after table creation by setting them under the 'Properties' structure.