Using cellfun for logical indexing - matlab

I have a cell data containing one row and four column. What i am trying to do is to go through elements in first column and see if an year '2018' is seen in the first column of each cell. When i perform this code, it will only give me the indices containing '2018' in the fourth cell. Not all the cells. Any help will be appreciated.
time = cellfun(#x, contains(x,'2018'),data{ii}(:,1))

I have created a small data sample as part of an example which I hope will help you solve the problem.
%Create cell array of strings.
data = {["2018","date","2018";"stack","cell2018","fun"],["data","stackoverflow","2018";"array","variable","data2018"]}
%Search for substring 2018 in the first column of every cell.
time = cellfun(#(x) contains(x(:,1),'2018'),data,'UniformOutput',0)
The output of time is a logical cell array:
>>time
{2×1 logical} {2×1 logical}
>>time{1}
1
0
>>time{2}
0
0
For the first cell, the column contains 2018 and stack, therefore 1 and 0 are returned.
For the second cell, the column contains data and array, therefore 0 and 0 are returned.
If you wish to find the indexes from the logical array, you can use the find function with outputs [row,col].

Related

How to substract a value from each row in a cell in Matlab?

I have a cell with dimension 41X41 as shown below
that has values equal to 1, it means all its values are equal to ones as shown below:
Based on many values, I could not include it here in one figure, but its dimension is 41 x 41.
What I was trying to do is calculate the number of ones in each row minus one as shown in the snippet of line code below:
ccc = sum(isSmaller{cc,:} == 1)-1
In order to get a cell with 1 row with 40 columns dimension that has 40s. as shown below:
My problem is instead of 40 columns is still showing 41 columns after deleting one from each row as indicated below.
May I get assistance, please? I need it to be 1 row with 40 columns.
Note: I do not care for the first 40 rows or columns or the lasts or the middle ones. I just need it to be done by itself only by minus one.
After that, I need to sum all the 40s in this ccc = 1x40.
Below is my try:
for cc = 1:length(isSmaller)
ccc = sum(isSmaller{cc,:} == 1)-1
end
If I understand correctly, isSmaller is a 1-by-1 cell array whose single cell contains a 41-by-41 matrix of logical values all equal to 1 (true):
isSmaller={true(41)};
Then you wish to calculate the sum of each row of this matrix inside of a cell and subtract one from the result:
sum(isSmaller{1},1)-1
But since you only care about the first 40 rows you can trim off the last row with:
sum(isSmaller{1}(:,1:40),1)-1
Or:
sum(isSmaller{1}(:,1:end-1),1)-1
This returns a 1-by-40 matrix where each element is 40.
Finally, you want to sum over the 40 elements of this matrix:
sum(sum(isSmaller{1}(:,1:end-1),1)-1)
This returns 1600, as expected.
No for loops are needed if this is all you need to do and your example is representative. I urge you to read through Matlab's documentation on cell arrays, in particular on how to access data within them.

Combine elements of a cell into a matrix

I have a cell (called AA ) that contains 1 row * 36 columns (as shown in the attached image)
As we could see that each column in that cell is a matrix ( inside each column there are 1*3 data points )
I need to have an array that has 36 Rows * 3 columns in MATLAB
For example,
the first column in the Cell will be converted into 1 Row and three columns, the second column in the Cell will be converted in the same way and finally put them all of them together in order to generate an array that contains 36 Rows and 3 Columns
as shown in this example
-1.48247427405830e-15 0.185513882360673 -0.185513882360676
-9.59200039657764e-16 0.211729497802758 -0.211729497802760
3.69087930153418e-16 0.224791092084074 -0.224791092084073
You can just use cat to concatenate the rows and use {:} indexing to create a comma separated list
output = cat(1, AA{:})
In addition to the answer of the gentleman Suever these are 2 methods as well that can be used to solve the same question
output =cell2mat(AA(:))
or, more simply,
output = vertcat(AA{:})

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

Store a particular set points in a new cell array

I had asked a similar question few weeks back but I think that question was not framed properly so please excuse me for asking the same question again
I have a column vector with values
32.5
25.8
25.91
25.92
16.52
16.7
Now I want to create a cell array such that my first cell contains the first value, my second cell array contains value from 25.8 to 25.92 and finally my third cell array contains the values 16.52 and 16.7 .
How can I solve this problem.
Since you didn't explain why you want the vector split up, I assume the specified division is arbitrary. The following should do what you want, assuming v is the column vector:
c = {v(1) v(2:4) v(5:6)};
Basically you are constructing three new vectors out of pieces of the original, and putting them together into a cell array.
This is a way with for loop.
A = [...
32.5
25.8
25.91
25.92
16.52
16.7];
[U,~,ic] = unique(floor(A));
B = cell(length(U),1); % Result
for k = 1:length(A)
B{ic(k)} = [B{ic(k)} A(k)];
end
Thank to unique command the result is even sorted.