Add headers to matrix using table

147 views (last 30 days)
Charlie Chen
Charlie Chen on 5 Jul 2021
Edited: Peter Perkins on 29 Jul 2021
***** Full code in the end *****csv.files attached*******
Hello community,
I am using Matlab R2020b.
I've bumped into an issue here, could use some help:
I've got a matrix of test data, and want to create a reuseable code to export it.
Since I don't know how many tests I will do next time, I decide to use a loop to genereate headers.
With this loop, I get the a string array as my "headers". Header is a 1x4 string. I also tried to generate a cell structure - tem (1x4 cell containing string)
% Generate headers
Header = ["Time"]
for filei = 1 : numberoffiles
Header(filei+1) = strcat("Test",num2str(filei))
end
tem = num2cell(Header)
Then I want to use the table function to add the header row, using "VariableNames" argument.
% add headers to the matrix
output = table (datapool,'VariableNames',Header)
I got rejected. Error message:
The VariableNames property must contain one name for each variable in the table.
In this instance, it is a 1x4 string array against a 200000x4 double matrix, the numbers should match. I don't understand why not.
********************************
I also tried to throw a cell arry to it - doesn't work either.
% add headers to the matrix
output = table (datapool,'VariableNames',tem)
Error message: The VariableNames property is a cell arry of character vectors. To assgin multiple variable names, specify nonempty names in a string array or a cell array of character vectors.
I know I did not sumbit the right data - the cells contain strings instead of characters. However, I don't know how to change the generator to generate character arrays.
Can you please share some insights?
Full code: files attached.
% Use pop box to select data.
filename = uigetfile(".csv","MultiSelect","on") % note filename is a cell struture, you cannot use dot reference for this structure.
% to retrieve the data in the cell struture, you need to use {} brackets.
% The result is the content of the indexed cell.
% see how many files are in this folder
numberoffiles=length(filename)
% import the files into matrices
datapool = nan(200000,numberoffiles) % initialize a matrice to store data
for filei = 1:numberoffiles
t = table2array(readtable (filename{filei},"NumHeaderLines",11))
%Clean data: remove entries less than 0.01.
validindex = find(t>=0.01);
t = t(validindex)
T = [t;nan(200000-height(t),1)] % fill emptycells with NaNs to fit datapool.
datapool (:,filei) =T % put data in the target location.
end
%create time stamp for the entries
t = transpose([1:200000])
t = (t-1) * 0.0005
datapool = [t,datapool]
%plot the dataset
plot(datapool(:,1),datapool(:,2),datapool(:,1),datapool(:,3),datapool(:,1),datapool(:,4))
% add headers to the matrix ( this method converts everything to a string
% table.)
% Header = ["Time"]
% for filei = 1 : numberoffiles
% Header(filei+1) = strcat('Test',num2str(filei))
% end
%
% output = [Header;num2cell(datapool)]
% this makes a file of strings, even the numbers are strings.
% Generate headers
Header = ["Time"]
for filei = 1 : numberoffiles
Header(filei+1) = strcat("Test",num2str(filei))
end
tem = num2cell(Header)
% add headers to the matrix
output = table (datapool,'VariableNames',Header)

Accepted Answer

dpb
dpb on 6 Jul 2021
Use new string class features here --
nFiles=4;
Header=["Time", "Test "+string(1:nFiles)];
returns a string array as
>> Header
Header =
1×5 string array
"Time" "Test 1" "Test 2" "Test 3" "Test 4"
>>
Then later on with
% add headers to the matrix
output = table (datapool,'VariableNames',Header)
The VariableNames property must contain one name for each variable in the table.
"In this instance, it is a 1x4 string array against a 200000x4 double matrix, the numbers should match."
It doesn't match because your use of table tells it to make a table of the array datapool as a single variable which is an Nx4 array, not four separate variables, one for each column.
What you want here is array2table instead --
tDP=array2table(datapool,'VariableNames',Header);
excepting if nFiles=4 as set above to create the header, you'll still get the same error because you've got the Nx4 array but five elements in the Header array. You need the time column as well. If it is one of the columns in the array, then nFiles will have to be 3 in this case, not four.
  6 Comments
Samuel Katongole
Samuel Katongole on 13 Jul 2021
In studying this problem, I have tried and gone through the code; and also tried out the suggested
tDP=array2table(datapool,'VariableNames',Header);
But it has yielded me the same error...I have observed the the following info should be paid attention to:
"The VariableNames property must be a cell array, with each element containing one nonempty character vector." found in the table VariableNames documentation. So the problem is solved by being able to convert the string array, Header, to a cell array of character vectors. This is achieved using the cellstr function. I have tried the following code and got the result shown below (Hope it is this that the questioner sought after)
for filei=1:nFiles
%update Header as nFiles changes/increases
Header=["Time", "Test"+string(1:nFiles)];
output=array2table(datapool);
output.Properties.VariableNames=cellstr(Header);
end
For the first ten rows of the output table....

Sign in to comment.

More Answers (1)

Samuel Katongole
Samuel Katongole on 13 Jul 2021
In studying this problem, I have tried and gone through the code; and also tried out the suggested
tDP=array2table(datapool,'VariableNames',Header);
But it has yielded me the same error...I have observed the the following info should be paid attention to:
"The VariableNames property must be a cell array, with each element containing one nonempty character vector." found in the table VariableNames documentation. So the problem is solved by being able to convert the string array, Header, to a cell array of character vectors. This is achieved using the cellstr function. I have tried the following code and got the result shown below (Hope it is this that the questioner sought after)
for filei=1:nFiles
%update Header as nFiles changes/increases
Header=["Time", "Test"+string(1:nFiles)];
output=array2table(datapool);
output.Properties.VariableNames=cellstr(Header);
end
For the first ten rows of the output table....
  1 Comment
Peter Perkins
Peter Perkins on 29 Jul 2021
Samuel, you must be using a version of MATLAB from around 2016 (or something funny is going on). From sometime around 2018, the variable names need not be a cellstr.
Also a minor suggestion:do the creation and naming all on one line.
output=array2table(datapool,'VariableNames',Header)

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!