Concatenate and pull out data from cell array - matlab

I have a cell array called d_O3 of size 3x15.
Here's what the first row looks like:
10x29 cell
31x29 cell
40x29 cell
...
I want to turn column one inside each cell into a column array and vertically concatenate them all together.
Here's what I've done so far:
years = 1999:2013; % The 15 columns
m = 1; % Row 1. I'd like to be able to run a loop for the other rows to do the same thing, but I haven't figured out how.
for y = 1:numel(years)
data{y,1} = d_O3{m.y}(:,1);
end
This creates a 15x1 cell that looks like this inside:
31x1 cell
40x1 cell
42x1 cell
...
Inside each cell (i.e. inside 31x1), there's a column array of strings. But I want it to all concatenate together so it looks like:
06-029-0001-88101
06-073-0010-88101
...
In other words, I want to make vertically concatenate all the cells above.
I can do it by doing the following:
vertcat(data{1,1},data{2,1},...)
But that would mean typing out data{i,1} 15 times. What's an easier way?

vertcat(data{1:15,1})
or
vertcat(data{:,1})
It creates a comma separated list which is passed to vertcat.

Related

Copy array by indexing cell numbers

I am trying to extract specific columns from a "nested" array, the columns I need are nested, there are about a thousand columns, of which I only need the ones marked by index in another part of the array.
I have one Array{1,15} containing cells with numerical values (e.g. 2,5,10,53). These values are the index numbers i need to extract from another array.
indexnum = OutArray{1,15}(:);
Which arranges them in a column instead of a row, totally not necessary but seemed easier for me to progress with this.
Then I have the array containing the actual columns I want to extract/copy to a new array.
OutArray{1,14}{i,1}
So by the example numbers above, I need to copy column 2,5,10 and 53 to another array.
One of my more current attempts looks like this:
NewArray = []; %create new array
indexnum = OutArray{1,15}(:); %copy right index values to column
for i = indexnum{:} %use numeric value of every cell
NewArray = [NewArray, OutArray{1,14}{1,i}] %copy corresponding columns to NewArray
end
I also tried to use cell2mat(indexnum(1,:)), but that didn't help either.
To make clear the structure of the array:
OutArray{1,15} Contains cells with 1 value per column, which are index numbers for other array
OutArray{1,14} contains nested cells, 1 cell per column
OutArray{1,14}{1,x} contains columns with ~30 values per column, of which I want to copy the columns with the right indexes
For another array in which I just needed to copy all columns this code worked fine:
new1 = [];
for i = 1:length(OutArray{1,4})
new1 = [new1, OutArray{1,4}{i,1}]
end
It was a bit hard to understand because of so many cells into cells but your screenshots were very helpful. I will first highlight the errors and needed changes in your attemp:
NewArray = []; %create new array
indexnum = OutArray{1,15}(:); %copy right index values to column
for i = indexnum{:} %use numeric value of every cell
NewArray = [NewArray, OutArray{1,14}{1,i}] %copy corresponding columns to NewArray
end
Doing OutArray{1,15}(:) is exactly the same as OutArray{1,15} as you are just selecting the full cell of cells.
Your for loop uses indexnum{:} as the iterator but {:} returns a comma separated list and it does not work like (:) for arrays that give the full vector instead. In this case, when you assign indexnum{:} to a variable you get only the first element of the list. An example to ilustrate this:C = {1, 2, 3}; C{:} displays the full list, but x = C{:} only makes x = 1. To get all the elements you could group them in an array by doing: x = [C{:}].
So in your case you just need to add brackets to for i = [indexnum{:}] to get the iterator working.
To sum up, your code would be changed to:
NewArray = []; %create new array
indexnum = OutArray{1,15}; %copy right index values to column
for i = [indexnum{:}]
NewArray = [NewArray, OutArray{1,14}{1,i}}];
end
In addition, you could avoid the for loop and variables initialization with this single line code:
NewArray = [OutArray{1,14}{1,[OutArray{1,15}{1,:}]}];
As you can see, it just takes row 1 of your data OutArray{1,14} and the columns specified at each element of the indexes OutArray{1,15}. Brackets are needed twice because when indexing a cell with curly braces with more than one index at a time you always get a list and need to convert into an array as explained above.

Writing the output of variable length cells into a single column cell array in MATLAB

I am trying to write the output from a variable length cell array to a single column cell array.
Eg:
I have
A a;b
B c
C b;c
D a;b;d
E e;g;h
F a;b
as the input file. I want to read all the entries in the second column into separate cells in a row and store the output as the following:
a
b
c
b
c
a
b
d.... and so on.
I tried
for m=1:size(txt)
c(:,m)=strsplit(txt{m},';');
end
However, I am unable to write the output into a column and getting the following error:
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
I understand that the dimensions of c should be more than that of size(txt) but I am not sure how to enter write the output from c into the first empty cell present in the column.
This is because you have declared c to be a matrix but you want it to be a single column. In addition, strsplit creates a cell array of results here each split string is placed in an element in the cell array. Also, this cell array is a row-wise cell array, meaning that you will get a cell array of dimensions 1 x N where N is the total number of strings resulting from the call the strsplit.
As such, what I would recommend you do is create a master cell array to store all of the strings as you iterate through each row, then concatenate and create one final cell array at the end.
Assuming the code you wrote up until this point is correct, do something like this:
c = cell(numel(txt), 1);
for m = 1 : numel(txt)
c{m} = strsplit(txt{m}, ';');
end
c = horzcat(c{:});
The first line creates a master cell array to store our string split characters per line of the text file. Next, for each line of the file, we split the string with the semicolon character as the delimiter and we place these split results into the right cell in the master array. Once this is finished, we use horzcat to place all of the characters into a single row of cells in the end. This creates a row of cell array elements though. Using horzcat is required as we are concatenating many row-wise cell arrays together into a single row. Trying to do this vertically will give you an error. Simply transpose the result if you want a column:
c = horzcat(c{:}).';

subindex into a cell array of strings

I have a 6 x 3 cell (called strat) where the first two columns contain text, the last column has either 1 or 2.
I want to take a subset of this cell array. Basically select only the rows where the last column has a 1 in it.
I tried the following,
ff = strat(strat(:, 3), 1:2) == 1;
The error message is,
Function 'subsindex' is not defined for values of class 'cell'.
How can I index into a cell array?
Cell arrays are accessed through braces {} instead of parentheses (). Then, as a 2nd subtlety, when pulling values out of a cell arrays, you need to gather them...for numerics you gather them into regular arrays using [] and for strings you gather them into a new cell array using {}. Confusing, eh?
ff = { strat{ [strat{:,3}]==1 , 1:2 } };
Gathering into cell arrays this way can often give the wrong shape when you're done. So, you might try something like this
ind = find([strat{:,3}]==1); %find the relevant indices
ff = {{strat{ind,1}; strat{ind,2}}'; %this will probably give you the right shape

Cell Array: show content and print name cell UITABLE

It is a basic problem but I am not so much experienced in Matlab(Guide).
What I have now is a cell array called Z with 21x2 elements: 21 rows 2 columns.
What I would like to do is to get only the first column (to show only 21x1).
Then, in this column there is a list of names. Inside the 21 rows of this cell there are repeated names. I would like to run through each row of this 21x1 column, detect which are repeated. The repeated ones should be printed in the uitable in a white colour.
Any ideas?
I believe this should deal with the core of your question:
A={'abc' 6;'de' 7;'abc' 8};
[C, ia] = unique(A(:,1));
idx = setdiff(1:size(A,1),ia);
A(idx,1)
This code will list all duplicates.

find top n numeric cells in a cell array

Hi I have a cell array 2 x 1000. the first column holds numeric (double) values, the second holds a string. i would like the find all cells in the first column that are above a certain value, and bring back the corresponding cells in the second column. I have tried strcamp and various others but obviously they are for strings. I also tried doing
sortrows(mycell(1,:));
so i could pick the first 50 rows off or whateever, but this didn't seem to order the cell array. but really i would like to specifiy a threshold on the first column of the cell array.
How do I do this?
thanks.
If C is your cell array:
nums = [C{:,1}];
{:} converts C into a comma separated list (so {:,1} only converts the first column) and then [] collects the results into a normal array. After that it's simple:
index = nums > Threshold;
C(index,:)
OR in a one liner:
C([C{:,1}] > Threshold, :) %// Or C([C{:,1}] > Threshold, 2) as Luis said