For Matlab, Import data from xlsx, how to get 1st row as variable name, and rest of the column as data for variable name - matlab

In my excel file. The very first row in each column is a string. The rest of the column is data for that string, i.e
'time'
1
2
3
4
I want to take the first row in excel, and make that the variable name in Matlab, and the rest of the column data is numerical data for that variable. So in Matlab, time would be a column vector of numbers 1, 2 ,3 ,4.
I can't get this to work.

how about
[val nms] = xlsread( xlsFileName );
assert( size(val,2) == size(nms,2), 'mismatch number of columns and number of names');
for ci=1:size(val,2)
eval( [ nms{ci}, ' = val(:,ci);' ] ); % name the column
end
What makes this work:
This code calls xlsread with two output variables. This way xlsread puts the numeric data into the first variable, and text data into the second. See xlsread doc for more info.
Using eval to assign values to variable (time) which name is stored in another variable (nms{1}). The argument of the eval commands is a string time = val(:,1);, which the Matlab command that assigns the values of the first column of data (val(:,1)) to a new variable named time.

Related

Convert a table column to a matrix in Matlab

I have a Table (T) as shown below:
>> Name = {'John';'Mary';'Martha'};
Age = [10.8;15.11;20.22];
T=table(Name,Age);
>> T
T =
3×2 table
Name Age
________ _____
'John' 10.8
'Mary' 15.11
'Martha' 20.22
Converting the Age column to a matrix works fine, if I use:
cell2mat(table2cell(T(:,2)))
But doesn't work if I use:
cell2mat(table2cell(T.Age))
and throws the following errror:
>> cell2mat(table2cell(T.Age))
Undefined function 'getVars' for input
arguments of type 'double'.
Error in table2cell (line 15)
t_vars = getVars(t);
Is there any way I could use the column name T.Age instead using T(:,2) while converting this column into a matrix ?
From the Access Data in a Table doc on the MathWorks site
Parentheses allow you to select a subset of the data in a table and preserve the table container.
while
Dot indexing extracts data from one table variable. The result is an array of the same data type as extracted variable. You can follow the dot indexing with parentheses to specify a subset of rows to extract from a variable.
So, if you use T.Age to access the data, the result should already be a matrix, i.e. you don't need to do any conversions using table2cell or cell2mat.

Saving a literal file name as a variable in Matlab

My goal is to load some files listed in the table, extract the data, and save the results as a variable of the first file name. The lists in the table are user-input characters, which represent the names of the files that will be loaded soon. I'll give you an example because you may not understand what I mean. When A,B,C (strings) are listed in the table, my code will find where they are located(eg A.txt) and load their data. After the data has been collected from them, the results are saved in the name of the table like this : A(variable)= result_data(:4). Here is my code. please let me know the wrong place. (Note that table is nx1 cell array using uitable.)
function pushbutton1_Callback(hObject, eventdata, handles)
data = get(handles.uitable,'data'); % get strings in table
for i = 1:size(data(:,1)) % count the #strings
fid = fopen([ data(i),'.csv' ]); %load the data and extract what I need
...
fclose(fid);
data(i) = result(row_1:row_2 , 4) % this is the result_data
% data(i) is variable string, so I am not sure whether to use the eval function.
end
Without having your table to debug further here is my suggestions. data is probably a cell array since you are pulling it from a uitable as below.
data = get(handles.uitable,'data'); % get strings in table
So this line should error:
fid = fopen([ data(i),'.csv' ]);
Change it to this:
fid = fopen([ data{i},'.csv' ]);
or this:
fid = fopen([ char(data(i)),'.csv' ]);
When saving your results to the variable name which matches your string I would suggesting using a structure with dynamic field names instead of a bare variable ... otherwise you will probably have to use eval which should be avoided.
So this (which isn't what you asked for):
data(i) = result(row_1:row_2 , 4) % this is the result_data
Should become:
outData.(data{i}) = result(row_1:row_2 , 4) % this is the result_data
If data is a cell array like you said containing {'A','B','C',...}
Then outData would be of the form below and contain each results.
outData.A
outData.B
outData.C

Convert a column of a table to vector

I have a table named cellName of size 10000*1. Each entry is a character string of cell names. Each cell name is of different length.
And I want to coerce it into a vector with 10000 elements. How can i do that in matlab? It should be very easy as that in r but i didn't find such command in matlab.
OR: I used readtable to load the 10000*1 table from csv file at the very beginning. It would be great if I can directly read the 10000*1 entries as a single vector too. This is what i did at first.
cellName = readtable('cell.csv');
cellName=cellName(1:10000,1);
Thank you in advance!
Clear example: A is a table of 5*1.
A= apple
banana
pear
peach
watermelon
And i want to coerce A into a vector of 5 elements: A=[apple,banana,pear,peach,watermelon] instead of a table
If a character cell array is what you want, I may have your answer. I also suggest you to read how to access data in a table.
readtable returns a Matlab table data type when succeeded. The table can be accessed like struct with your column name as the fieldname, or be indexed by {} operator like you would access a cell array.
In your example, assuming A is the return value of readtable and your
A = table({'apple','banana','pear','peach','watermelon'}','variableNames',{'cellName'})
Then you can either call
cellName = A.cellName
or
cellName = A{:,1}
to get your cell array.

How to extract columns of data from .txt files MATLAB

I have some data in a .txt file. that are separated by commas.
for example:
1.4,2,3,4,5
2,3,4.2,5,6
24,5,2,33.4,62
what if you want the average of columns, like first column (1.4,2 and 24)? or second column(2,3 and 5)?
I think putting the column in an array and using the built in mean function would work, but so far, I am only able to extract rows, not columns
instead of making another thread, I thought i'd edit this one. I am working on getting the average of each column of the well known iris data set.
I cut a small portion of the data:
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
delimiterln= ',';
data = importdata('iris.txt', delimiterln);
meanCol1 = mean(data(:,1))
meanCol2 = mean(data(:,2))
meanCol3 = mean(data(:,3))
meanCol4 = mean(data(:,4))
Undefined function 'sum' for input arguments of type 'cell'.
Error in mean (line 115)
y = sum(x, dim, flag)/size(x,dim);
Error in irisData(line 6)
meanCol1 = mean(data(:,1))
it looks like there is an error with handling data type...any thoughts on this? I tried getting rid of the last column, which are strings. and it seems to work without error. So i am thinking that it's because of the strings.
Use comma separated file reading function:
M = csvread(filename);
Now you have the matrix M:
col1Mean=mean(M(:,1));

Convert dataset column to obsnames

I have many large dataset arrays in my workspace (loaded from a .mat file).
A minimal working example is like this
>> disp(old_ds)
Date firm1 firm2 firm3 firm4
734692 880,0 102,1 32,7 204,2
734695 880,0 102,0 30,9 196,4
734696 880,0 100,0 30,9 200,2
734697 880,0 101,4 30,9 200,2
734698 880,0 100,8 30,9 202,2
where the first row (with the strings) already are headers in the dataset, that is they are already displayed if I run old_ds.Properties.VarNames.
I'm wondering whether there is an easy and/or fast way to make the first column as ObsNames.
As a first approach, I've thought of "exporting" the data matrix (columns 2 to 5, in the example), the vector of dates and then creating a new dataset where the rows have names.
Namely:
>> mat = double(old_ds(:,2:5)); % taking the data, making it a matrix array
>> head = old_ds.Properties.VarNames % saving headers
>> head(1,1) = []; % getting rid of 'Date' from head
>> dates = dataset2cell(old_ds(:,1)); % taking dates as column cell array
>> dates(1) = []; % getting rid of 'Date' from dates
>> new_ds = mat2dataset(mat,'VarNames',head,'ObsNames',dates);
Apart from the fact that the last line returns the following error, ...
Error using setobsnames (line 25)
NEWNAMES must be a nonempty string or a cell array of nonempty strings.
Error in dataset (line 377)
a = setobsnames(a,obsnamesArg);
Error in mat2dataset (line 75)
d = dataset(vars{:},args{:});
...I would have found a solution, then created a function (such to generalize the process for all 22 dataset arrays that I have) and then run the function 22 times (once for each dataset array).
To put things into perspective, each dataset has 7660 rows and a number of columns that ranges from 2 to 1320.
I have no idea about how I could (and if I could) make the dataset directly "eat" the first column as ObsNames.
Can anyone give me a hint?
EDIT: attached a sample file.
Actually it should be quite easy (but the fact that I'm reading your question means that having the same problem, I first googled it before looking up the documentation... ;)
When loading the dataset, use the following command (adjusted to your case of course):
cell_dat{1} = dataset('File', 'YourDataFile.csv', 'Delimiter', ';',...
'ReadObsNames', true);
The 'ReadObsNames' default is false. It takes the header of the first column and saves it in the file or range as the name of the first dimension in A.Properties.DimNames.
(see the Documentation, Section: "Name/value pairs available when using text files or Excel spreadsheets as inputs")
I can't download your sample file, but if you haven't yet solved the problem otherwise, just try the suggested solution and tell if it works. Glad if I could help.
You are almost there, the error message you got is basically saying that Obsname have to be strings. In your case the 'dates' variable is cell array containing doubles. So you just need to convert them to string.
mat = double(piHU(:,2:end)); % taking the data, making it a matrix array
head = piHU.Properties.VarNames % saving headers
head(1) = []; % getting rid of 'Date' from head
dates = dataset2cell(piHU(:,1)); % taking dates as column cell array, here dates are of type double. try typing on the command window class(dates{2}), you can see the output is double.
dates(1) = []; % getting rid of 'Date' from dates
dates_str=cellfun(#(s) num2str(s),dates,'UniformOutput',false); % convert dates to string, now try typing class(dates_str{2}), the output should be char
new_ds = mat2dataset(mat,'VarNames',head,'ObsNames',dates_str); % construct new dataset.