MATLAB: create a list/cell array of strings - arrays

data = {};
data(1) = 'hello';
gives this error Conversion to cell from char is not possible.
my strings are created inside a loop and they are of various lengths. How do I store them in a cell array or list?

I believe that the syntax you want is the following:
data = {};
data{1} = 'hello';

Use curly braces to refer to the contents of a cell:
data{1} = 'hello'; %// assign a string as contents of the cell
The notation data(1) refers to the cell itself, not to its contents. So you could also use (but it's unnecessarily cumbersome here):
data(1) = {'hello'}; %// assign a cell to a cell
More information about indexing into cell arrays can be found here.

Related

Concatenate cell array in MATLAB

In Matlab you can concatenate arrays by saying:
a=[];
a=[a,1];
How do you do something similar with a cell array?
a={};
a={a,'asd'};
The code above keeps on nesting cells within cells. I just want to append elements to the cell array. How do I accomplish this?
If a and b are cell arrays, then you concatenate them in the same way you concatenate other arrays: using []:
>> a={1,'f'}
a =
1×2 cell array
{[1]} {'f'}
>> b={'q',5}
b =
1×2 cell array
{'q'} {[5]}
>> [a,b]
ans =
1×4 cell array
{[1]} {'f'} {'q'} {[5]}
You can also use the functional form, cat, in which you can select along which dimension you want to concatenate:
>> cat(3,a,b)
1×2×2 cell array
ans(:,:,1) =
{[1]} {'f'}
ans(:,:,2) =
{'q'} {[5]}
To append a single element, you can do a=[a,{1}], but this is not efficient (see this Q&A). Instead, do a{end+1}=1 or a(end+1)={1}.
Remember that a cell array is just an array, like any other. You use the same tools to manipulate them, including indexing, which you do with (). The () indexing returns the same type of array as the one you index into, so it returns a cell array, even if you index just a single element. Just about every value in MATLAB is an array, including 6, which is a 1x1 double array.
The {} syntax is used to create a cell array, and to extract its content: a{1} is not a cell array, it extracts the contents of the first element of the array.
{5, 8, 3} is the same as [{5}, {8}, {3}]. 5 is a double array, {5} is a cell array containing a double array.
a{5} = 0 is the same as a(5) = {0}.

finding a str in MatLab cells

I am currently using MatLab R2014a
I have one array and one cell:
MyArray = ['AA1', 'AA2', 'AB1', 'AB2', 'Acc1', 'Acc2'];
MyCell = {'Name1AA1', 'Name2AA1', 'Name3Acc2', 'Name4AB2', 'Name5AD1};
MyArray consists of code names that are repeatable throughout MyCell.
I would like to check if any of the strings in MyArray are in MyCell and if it is, save the name to a new cell.
For now I have:
NewCell = {};
for i = 1:length(MyCell)
for j = 1:length(MyArray)
Find = strfind(MyCell(i), MyArray)
if ~isempty(Find)
NewCell = {NewCell; MyCell(j)}
end
end
end
However, when I use strfind I get this error message:
Undefined function 'strfind' for input arguments of type 'char'
If I use strcmp instead of strfind, I get an array of everything in MyCell repeated by the number of elements in MyArray.
My Ideal output would be:
NewCell1 = {'Name1AA1', 'Name2AA1'}
NewCell2 = {'Name4AB2'}
NewCell3 = {'Name3Acc2'}
ie, no new cell for the code names that are not present in MyArray or no new cell if there is a code name in MyArray but not in MyCell.
Any help is welcome, and thanks for your time
You can use a combination of regular expressions to achieve the desired output. Your approach of wanting to name variables dynamically is not recommended and will lead to code which is harder to debug. Use indexing instead.
You can read this informative post on Matlab's forum to understand why.
%Your input data.
MyArray = ['AA1', 'AA2', 'AB1', 'AB2', 'Acc1', 'Acc2'];
MyCell = {'Name1AA1', 'Name2AA1', 'Name3Acc2', 'Name4AB2', 'Name5AD1'};
%Find common elements between MyArray and MyCell.
elem = cellfun(#(x) regexp(MyArray,x(end-2:end),'match'),MyCell,'un',0);
%Eliminate duplicates.
NewCell = unique([elem{:}]);
%Find elements in MyCell which end with NewCell elements and group them.
NewCell = cellfun(#(x) regexp([MyCell{:}],strcat('Name\d\w?',x),'match'),NewCell,'un',0);
%Join elements.
NewCell{1} = {strjoin(NewCell{1},''',''')};
NewCell{1} = {'Name1AA1','Name2AA1'}
NewCell{2} = {'Name4AB2'}
NewCell{3} = {'Name3Acc2'}

How do I convert a cell array w/ different data formats to a matrix in Matlab?

So my main objective is to take a matrix of form
matrix = [a, 1; b, 2; c, 3]
and a list of identifiers in matrix[:,1]
list = [a; c]
and generate a new matrix
new_matrix = [a, 1;c, 3]
My problem is I need to import the data that would be used in 'matrix' from a tab-delimited text file. To get this data into Matlab I use the code:
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
which outputs a cell array of two 3x1 arrays. I want to get this into one 3x2 matrix where the first column is a character, and the second column an integer (these data formats will be different in my implementation).
So far I've tried the code:
matrix_1 = cell2mat(matrix(1,1));
matrix_2 = cell2mat(matrix(1,2));
matrix = horzcat(matrix_1, matrix_2)
but this is returning a 3x2 matrix where the second column is empty.
If I just use
cell2mat(matrix)
it says it can't do it because of the different data formats.
Thanks!
This is the help of matlab for the cell2mat function:
cell2mat Convert the contents of a cell array into a single matrix.
M = cell2mat(C) converts a multidimensional cell array with contents of
the same data type into a single matrix. The contents of C must be able
to concatenate into a hyperrectangle. Moreover, for each pair of
neighboring cells, the dimensions of the cell's contents must match,
excluding the dimension in which the cells are neighbors. This constraint
must hold true for neighboring cells along all of the cell array's
dimensions.
From what I understand the contents you want to put in a matrix should be of the same type otherwise why do you want a matrix? you could simply create a new cell array.
It's not possible to have a normal matrix with characters and numbers. That's why cell2mat won't work here. But you can store different datatypes in a cell-array. Use cellstr for the strings/characters and num2cell for the integers to convert the contents of matrix. If you have other datatypes, use an appropriate function for this step. Then assign them to the columns of an empty cell-array.
Here is the code:
fn_matrix = 'data.txt';
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
X = cell(size(matrix{1},1),2);
X(:,1) = cellstr(matrix{1});
X(:,2) = num2cell(matrix{2});
The result:
X =
'a' [1]
'b' [2]
'c' [3]
Now we can do the second part of the question. Extracting the entries where the letter matches with one of the list. Therefore you can use ismember and logical indexing like this:
list = ['a'; 'c'];
sel = ismember(X(:,1),list);
Y(:,1) = X(sel,1);
Y(:,2) = X(sel,2);
The result here:
Y =
'a' [1]
'c' [3]

MATLAB cell2mat unique error cell array

I created a cell Array like this
A{1} = {'aa','b','d','aa'};
A{2} = {'c','d','aa'};
A{3} = {'bb','aa','bb','aa'};
now I wanna find the unique words
b=cell2mat(A)
unique(b)
but I get this Error: Error using cell2mat (line 52) Cannot support cell arrays containing cell arrays or objects.
I'm fairly new to matlab. Am I doing something wrong here?
A{1} = {'aa','b','d','aa'};
A{2} = {'c','d','aa'};
A{3} = {'bb','aa','bb','aa'};
unique([A{:}])
There you go. The {:}, (:) and [] operators are very useful in MATLAB. Get comfortable using them.

AS3 manipulation of multidimensional array

good day :)
Why is it that when i edit the hold:Array, the array:Array also gets editted?
To give an example:
function func(2, 2) { //x, y COORDINATE
var hold = array[2]; //GET COLUMN OF ARRAY
hold[2] = 2; //SET hold[x] to 2
trace(array[2][2]) //SAME AS hold[x] *but i didn't change array[x]'s value!*
}
STEP BY STEP analysis
array[] looks like this (for example):
1,1,1,1
1,1,1,1
1,1,1,1
1,1,1,1
Thus, var hold = array[y]: (where y=2)
1,1,1,1
and hold[x] = 2 (where x=2)
1,2,1,1
Now, tracing array[y][x] (where y=2, x=2)
1,2,1,1
But array[2][2] should be 1,1,1,1, because we didn't edit it's value!
Question
Why does array[] get edited when i only edited hold[]
This is because arrays (typeof will give Object) are passed by reference. To copy its values you need to clone an array in ActionScript.
Here's an explanation of this for ActionScript 2.0 (which also applies to ActionScript 3.0 but I couldn't find the version of this article for the latter).
Yes, arrays are stored against variables as a reference. This means that when you create your array array and then store it in hold to create a 2D array, you're simply storing a reference to array within hold.
For example, you would expect that if you stored a Sprite within an array and then edited that Sprite's values, that you would see those changes from anywhere else you've referenced the Sprite. This is the same for arrays.
var array:Array = [];
var another:Array = [];
var sprite:Sprite = new Sprite();
array.push(sprite);
another.push(sprite);
array[0].x = 10;
trace(another[0].x); // Also 10.
If you don't want this behaviour, you can use .slice() or .concat() to make a shallow clone of an array:
array.push(hold.slice()); // or
array.push(hold.concat());

Resources