Entering data into excel sheet using matlab - matlab

I am entering a dynamic data into excel sheet from a textbox. The problem is that it enters letter by letter in every cell.
This is the code I have tried:
>>function bntEnterData_callback(hObject,eventdata,handles)
>>val1 = get(handles.txt1,'string'));
>>val2 = get(handles.txt2,'string'));
>>val3 = get(handles.txt3,'string'));
>>values = [ val1 val2 val3]
>>filename= 'try.xls';
>>sheet= 1;
>>xkRange= 'A2';
>>xlswrite(filename,values,sheet,xlRange);

Assuming your handles.txt* are edit uicontrols, the 'String' property is going to be a character vector. Concatenating multiple character vectors just creates a longer vector:
a = 'foo';
b = 'bar';
values = [a b]
Which creates:
values =
'foobar'
When not explicitly provided a range of cells to write to, xlswrite will interpret the input single cell (or the default A1) as the starting point, and write all elements of the input array using the single cell as the origin. Because 'foobar' is an array of characters, this gives the expected behavior of:
To fix this, concatenate into a cell array:
a = 'foo';
b = 'bar';
values = {a b};
filename= 'try.xls';
sheet= 1;
xlRange= 'A2';
xlswrite(filename,values,sheet,xlRange);

Related

How to concatenate / assign string of different length to existing Matlab table?

Consider table in Matlab.
a = table();
a.c = 'a';
How can I add one row containing a string of different length to that table? i.e I want to get:
c
______
'a'
'aa'
For example this simple attempt gives an error:
b = table();
b.c = 'aa';
result = [a; b]
Error:
Could not concatenate the table variable 'c' using VERTCAT.
Caused by:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Due to how MATLAB's table objects treats the contained data, it tries to be smart with the data types. Occasionally when things try to be smart behind the scenes they get tripped up in ways that aren't necessarily readily apparent to the user.
What's happening here is that since your c column is created with a character array, MATLAB attempts to keep this column homogeneous and concatenate 'a' with 'aa'. This will error out due to MATLAB's handling of character arrays as matrices of characters, which comes with a size enforcement: all rows must have the same number of columns.
You have a couple options: use a string array (introduced in R2016b), or use a cell array. While string arrays are essentially cell arrays under the hood, they come with the advantage of dedicated string methods, allowing you to natively perform various string operations without needing to explicitly index into a cell array.
To change your code, simply use double quotes ("") instead of single quotes (''):
a = table();
a.c = "a";
b = table();
b.c = "aa";
T = [a;b]
Which returns:
T =
2×1 table
c
____
"a"
"aa"
Alternatively, you can explicitly force the type of c as a cell array:
a = table();
a.c = {'a'};
b = table();
b.c = 'aa';
T = [a; b]
Which returns the same.
If you have an entire column of data, you can create a column from a cell array
tbl = table();
tbl.mycol = {'some text';
'something else';
'third item'};
If you want to append a single items (like in a loop) you could do
tbl = table();
mycell = {'some text';
'something else';
'third item'};
tbl.mycol = {};
for ii = 1:numel(mycell)
tbl.mycol(ii) = mycell(ii);
end
Similarly, you can append to the end as you would an array
tbl.mycol(end+1) = {'fourth item'};
You can merge two tables by concatenating them using vertcat
myothercell = {'append this';
'...and this'};
tbl1 = table();
tbl1.mycol = mycell;
tbl2 = table();
tbl2.mycol = myothercell;
tbl3 = vertcat(tbl1, tbl2);

Creating a function with variable number of inputs?

I am trying to define the following function in MATLAB:
file = #(var1,var2,var3,var4) ['var1=' num2str(var1) 'var2=' num2str(var2) 'var3=' num2str(var3) 'var4=' num2str(var4)'];
However, I want the function to expand as I add more parameters; if I wanted to add the variable vark, I want the function to be:
file = #(var1,var2,var3,var4,vark) ['var1=' num2str(var1) 'var2=' num2str(var2) 'var3=' num2str(var3) 'var4=' num2str(var4) 'vark=' num2str(vark)'];
Is there a systematic way to do this?
Use fprintf with varargin for this:
f = #(varargin) fprintf('var%i= %i\n', [(1:numel(varargin));[varargin{:}]])
f(5,6,7,88)
var1= 5
var2= 6
var3= 7
var4= 88
The format I've used is: 'var%i= %i\n'. This means it will first write var then %i says it should input an integer. Thereafter it should write = followed by a new number: %i and a newline \n.
It will choose the integer in odd positions for var%i and integers in the even positions for the actual number. Since the linear index in MATLAB goes column for column we place the vector [1 2 3 4 5 ...] on top, and the content of the variable in the second row.
By the way: If you actually want it on the format you specified in the question, skip the \n:
f = #(varargin) fprintf('var%i= %i', [(1:numel(varargin));[varargin{:}]])
f(6,12,3,15,5553)
var1= 6var2= 12var3= 3var4= 15var5= 5553
Also, you can change the second %i to floats (%f), doubles (%d) etc.
If you want to use actual variable names var1, var2, var3, ... in your input then I can only say one thing: Don't! It's a horrible idea. Use cells, structs, or anything else than numbered variable names.
Just to be crytsal clear: Don't use the output from this in MATLAB in combination with eval! eval is evil. The Mathworks actually warns you about this in the official documentation!
How about calling the function as many times as the number of parameters? I wrote this considering the specific form of the character string returned by your function where k is assumed to be the index of the 'kth' variable to be entered. Array var can be the list of your numeric parameters.
file=#(var,i)[strcat('var',num2str(i),'=') num2str(var) ];
var=[2,3,4,5];
str='';
for i=1:length(var);
str=strcat(str,file(var(i),i));
end
If you want a function to accept a flexible number of input arguments, you need varargin.
In case you want the final string to be composed of the names of your variables as in your workspace, I found no way, since you need varargin and then it looks impossible. But if you are fine with having var1, var2 in your string, you can define this function and then use it:
function str = strgen(varargin)
str = '';
for ii = 1:numel(varargin);
str = sprintf('%s var%d = %s', str, ii, num2str(varargin{ii}));
end
str = str(2:end); % to remove the initial blank space
It is also compatible with strings. Testing it:
% A = pi;
% B = 'Hello!';
strgen(A, B)
ans =
var1 = 3.1416 var2 = Hello!

MATLAB select variables from the workspace with a specific name

I would like to select all the variables in my workspace whos name follow a specific pattern. For example, I would like to compute the mean for all the variables in my workspace starting with the name my_vars.
I tried the following code:
a = who('-regexp','my_vars*')
result = mean(eval(a))
Howevever the eval function doesn't work for cells. Is there any work arround?
who returned a cell array of char arrays (i.e. strings), with each element containing one variable name. You need to convert that to a string containing a comma-separated list of the names. Here's one way to do that:
my_vars1 = 1; my_vars2 = 2; my_vars3 = 3;
names = who('-regexp', 'my_vars*');
namelist = sprintf('%s,', names{:}); % sprintf reuses the format string if
% there are more inputs than format specifiers
namelist(end)=[]; % strip last comma
eval(sprintf('mean([%s])', namelist))
ans =
2

Function for comparing two cell arrays

I have a cell array (2000*10) with each cell containing a string such as '25:20:55'.
I want to write a function that accepts 10 inputs (say '25:02:33', '58:69:88', '25:54:96', '48:58:36', '58:54:88' and so on) and looks for a match in each column corresponding to input value for that particular column (i.e. the first input data corresponds to 1st column, 2nd to 2nd column of the stored data and so on.
How can I write a function for the above comparison?
Assuming the cell array contains strings, you can find matches using strcmp:
input = {'25:02:33', '58:69:88', '25:54:96', '48:58:36', '58:54:88'};
match_idx = strcmp(repmat(input, size(cell_data,1),1), cell_data);
If you only want to know if there are matches in the respective columns at all and do not care about the line index of the match, you can do
match = any(match_idx,1);
Use ismember
ismember(your_var, your_cell);
e.g.
c = {'a', 'b', 'c', 'd'};
ismember('b', c)
ans =
1
ismember('q', c)
ans =
0
In your case, something like could work
function arr = myfun(inputvec, inputmat)
for i=1:length(inputvec) %// where inputvec is the cell-vector with the strings you want to search for
arr(i) = ismember(inputvec{i}, inputmat{:,i});
end

Iterating through struct fieldnames in MATLAB

My question is easily summarized as: "Why does the following not work?"
teststruct = struct('a',3,'b',5,'c',9)
fields = fieldnames(teststruct)
for i=1:numel(fields)
fields(i)
teststruct.(fields(i))
end
output:
ans = 'a'
??? Argument to dynamic structure reference must evaluate to a valid field name.
Especially since teststruct.('a') does work. And fields(i) prints out ans = 'a'.
I can't get my head around it.
You have to use curly braces ({}) to access fields, since the fieldnames function returns a cell array of strings:
for i = 1:numel(fields)
teststruct.(fields{i})
end
Using parentheses to access data in your cell array will just return another cell array, which is displayed differently from a character array:
>> fields(1) % Get the first cell of the cell array
ans =
'a' % This is how the 1-element cell array is displayed
>> fields{1} % Get the contents of the first cell of the cell array
ans =
a % This is how the single character is displayed
Since fields or fns are cell arrays, you have to index with curly brackets {} in order to access the contents of the cell, i.e. the string.
Note that instead of looping over a number, you can also loop over fields directly, making use of a neat Matlab features that lets you loop through any array. The iteration variable takes on the value of each column of the array.
teststruct = struct('a',3,'b',5,'c',9)
fields = fieldnames(teststruct)
for fn=fields'
fn
%# since fn is a 1-by-1 cell array, you still need to index into it, unfortunately
teststruct.(fn{1})
end
Your fns is a cellstr array. You need to index in to it with {} instead of () to get the single string out as char.
fns{i}
teststruct.(fns{i})
Indexing in to it with () returns a 1-long cellstr array, which isn't the same format as the char array that the ".(name)" dynamic field reference wants. The formatting, especially in the display output, can be confusing. To see the difference, try this.
name_as_char = 'a'
name_as_cellstr = {'a'}
You can use the for each toolbox from http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each.
>> signal
signal =
sin: {{1x1x25 cell} {1x1x25 cell}}
cos: {{1x1x25 cell} {1x1x25 cell}}
>> each(fieldnames(signal))
ans =
CellIterator with properties:
NumberOfIterations: 2.0000e+000
Usage:
for bridge = each(fieldnames(signal))
signal.(bridge) = rand(10);
end
I like it very much. Credit of course go to Jeremy Hughes who developed the toolbox.