I would like to create a table from a matrix of spectra data, using a specific list of variables (column, which here correspond to 1000 spectral wavelenght values) instead of putting the name manually.
To do so, i use the array2table function, and matlab documentation shows that names for rows and label of variables must be put as cell arrays, (and not matrix). So I need to first convert my x-axis (spectral wavelenght) to a cell array. I use the following:
C = num2cell(xaxis); % to convert into a cell array (each cell contain 1 value)
isvarname C % to check that the variable is valid as a cell array
T = array2table(R,'RowNames', concentration,'VariableNames',C);
Here: R is the matrix, concentration is a Cell array 1x500, xaxis is the wavelenght of spectral data 1x1000 (which is ranged from 600 to 1800, approx. there is no null value).
Unfortunately, I got the following error:
"Error using array2table (line 62)
The VariableNames property must be a cell array, with each element containing one nonempty string."
which means I can input properly the columns (variable) names (while row names, however, works fine).
Note: i tried the
T.Properties.VariableNames = c but it is not working either.
I checked the other post on table name value but its not helping,
Any thought about this?
Thank you very much.
Maybe you mistyped your question's code, but it seems that you are using the array xaxis instead of C. Anyway, I suggest you try casting the cells content to strings this way
T = array2table(R,'RowNames', concentration,'VariableNames',cellfun(#(x)num2str(x),num2cell(xaxis),'uniformoutput',false));
Edit
Looking through the table docs it says that
Variable names, specified as the comma-separated pair consisting of 'VariableNames' and a cell array of character vectors that are nonempty and distinct. The number of character vectors must equal the number of variables. The variable names that you assign must be valid MATLAB® variable names. You can determine valid variable names using the function isvarname.
Furthermore, the isvarname function says that
A valid variable name begins with a letter and contains not more than namelengthmax characters. Valid variable names can include letters, digits, and underscores. MATLAB keywords are not valid variable names. To determine if the input is a MATLAB keyword, use the iskeyword function.
This means that you cannot use the xaxis values as variable names by themselves, you need to, at least, prepend a character and remove the decimal dot. You can do so with the following
T = array2table(R,'RowNames', concentration,...
'VariableNames',cellfun(#(x)['wavel_',regexprep(num2str(x),'.','_')],num2cell(xaxis),'uniformoutput',false));
This code will prepend 'wavel_' to the numerical string value. It will also replace the dots with underscores using the regexprep function. However, it seems like this is really unnecessary because the column names are not really informative. The array2table function's doc says that if you don't supply the 'variableNames' option it will do the following:
If valid MATLAB identifiers are not available for use as variable names, MATLAB uses a cell array of N character vectors of the form {'Var1' ... 'VarN'} where N is the number of variables.
Maybe using the default variable names is good enough.
Related
I want to take a cell array from the user containing the number of zeros and poles of each transfer function in a system identification app that I am designing in MATLAB's app designer.
User enters something like this:
{[2,1], [1,0]; [1,0], [2,1]}
EditField or TextArea treats this input as a char array or string, But I want to re-convert it to a cell array of numbers, not strings. How is that possible?
You can use eval to evaluate the string to get the resulting numbers. This works if it has numbers, variables and functions accessible from the workspace where you are running eval. See documentation for eval at https://www.mathworks.com/help/matlab/ref/eval.html. If there is a variable in the expression for example as, {[2,1], [1,0]; [1,0], a} with a defined in the base workspace then you need to use evalin. evalin lets you specify the workspace where the expression needs to be evaluated.
Finally if it is not a cell array and contains only an array of numbers then str2num also can do the job of converting the string to numbers.
I have a txt file with a bunch of parameters created by the external program.
Let us consider a simple example:
input.txt
a= 1
b= 2
c= 3
I can read both names and values in matlab 2018a:
[names, values]=textread('input.txt','%s%f');
As a result, names will be a 3x1 cell array with entries a=, b= and so on, whereas values will be a conventional 3x1 array of doubles.
In my current workspace, I want to initialize the obtained variables (with the corresponding names) and set them equal to the corresponding values.
In the example above, variables a=1, b=2 and c=3 should be created in the current workspace.
I have no idea how to do it...
Thanks!
Edit: in my actual example variable names can contain many characters/numbers (by the standard convention, variable names always start with the letter, not a digit), e.g.
Rcirc1= 30.0
SaveStride= 1000
You can use a combination of regexp and assignin to achieve the desired output:
%Read data.
data = fileread('input.txt')
%Extract variable name and value in named groups.
s = regexp(data,'(?<var>[A-Z]\w+)\D+(?<val>\d+(?:\.\d+)?)','names');
%Loop over struct s contents to create variables in workspace.
cellfun(#(x,y) assignin('base',x,str2double(y)),{s.var},{s.val})
The assignments in the text file can be directly evaluated by MATLAB. You don't need to extract them. In order to silence the text printed for each line you can use evalc
evalc(fileread('input.txt'));
What does following code do in Matlab? I searched documentation but ~ shows logical not. But I could not relate following output to anything about logical not.
[~, k ] = max([0.9 1.5 4.6; 3.31 0.76 5.4]
Output: 2 1 2
The ~ placeholder allows you to ignore an output from a function. Using this allows you to acknowledge that something is output by the function, but you do not have to allocate a variable to store the output in.
When a function returns values in Matlab the number of parameters it returns and the order of these parameters is important and allows you to know what each returned value is. You may sometimes come across situations where a function returns more values than you are interested in, and you can ignore the ones you are not interested in using ~.
In your example, M = max([0.9 1.5 4.6]) would return only the maximum value. If you want to know the index of the maximum value, you have to use [M,I] = max([[0.9 1.5 4.6]). If you need to know the index of the maximum value but are not interested in the actual value itself, you can use [~,I] = max([0.9 1.5 4.6]), and you thus do not need to allocate a variable to hold the maximum values.
The according reference you're looking for is the Symbol Reference, which states:
Tilde — ~
The tilde character is used in comparing arrays for unequal values,
finding the logical NOT of an array, and as a placeholder for an input
or output argument you want to omit from a function call. Not Equal to
...
Argument Placeholder
To have the fileparts function return its third output value and skip
the first two, replace arguments one and two with a tilde character:
[~, ~, filenameExt] = fileparts(fileSpec);
which is what #David suggested in his comment.
As a foreword, I have been searching for solutions to this, and I have tried a myriad of codes but none of them work for the specific case.
I have a variable that is the registration number of different UK firms. The data was originally from Stata, and I had to use a code to import non-numeric data into Matlab. This variable (regno) is numeric up until observation 18000 (approx). From then it becomes registration numbers with both letters and numbers.
I wrote a very crude loop that grabbed the initial variable (cell), took out the double quotations, and extracted the characters into a another matrix (double). The code is :
regno2 = strrep(regno,'"','');
regno3 = cell2mat(regno2);
regno4 = [];
for i = 1:size(regno3,1);
regno4(i,1) = str2double(regno3(i,1:8));
end
For the variables with both letters and numbers I get NaN. I need the variables as a double in order to use them as dummy indicator variables in MatLab. Any ideas?
Thanks
Ok I'm not entirely sure about whether you need letters all the time, but here regular expressions would likely perform what you want.
Here is a simple example to help you get started; in this case I use regexp to locate the numbers in your entries.
clear
%// Create dummy entries
Case1 = 'NI000166';
Case2 = '12ABC345';
%// Put them in a cell array, like what you have.
CasesCell = {Case1;Case2};
%// Use regexp to locate the numbers in the expression. This will give the indices of the numbers, i.e. their position within each entry. Note that regexp can operate on cell arrays, which is useful to us here.
NumberIndices = regexp(CasesCell,'\d');
%// Here we use cellfun to fetch the actual values in each entry, based on the indices calculated above.
NumbersCell = cellfun(#(x,y) x(y),CasesCell,NumberIndices,'uni',0)
Now NumbersCell looks like this:
NumbersCell =
'000166'
'12345'
You can convert it to a number with str2num (or srt2double) and you're good to go.
Note that in the case in which you have 00001234 or SC001234, the values given by regexp would be considered as different so that would not cause a problem. If the variables are of different lenghts and you then have similar numbers, then you would need to add a bit of code with regexp to consider the letters.
Hope that helps! If you need clarifications or if I misunderstood something please tell me!
I want to make a system content Fuzzy, so first I make the graphical system shape in GUI. The main sector of my system is a table that some columns of this table must be filled by user, other rows must be filled after Fuzzy processes. Then, I make the Fuzzy system separately, and when I want to insert cell type numbers (instead of Fuzzy input variables) to my Fuzzy system in MATLAB using command window, this error appeared:
"??? Undefined function or method 'min' for input arguments of type 'cell'."
Please help me to fix the problem.
Your problem is probably unrelated to your "Fuzzy" application.
From the error, you are either explicitly trying to min()over a cell array entries or passing cellinput arguments to a function that expects double.
% example cell array of doubles (one per entry)
N = 4; cellArray = mat2cell(randi(10, N, N), ones(N,1), ones(N,1));
% min of all
minCellArray = min([cellArray{:}]);
% min of two entries
minSubArray = min(cellArray{1}, cellArray{2});
Now compare the above with trying to do minSubArray = min(cellArray(1), cellArray(2)), which will generate the same error as the one you get.
Overall, beware of the cellArray{i} vs cellArray(i) assignment or passing (as input) to functions.