Subscripted assignment dimension mismatch when combining corresponding array and cell array values in matlab - arrays

I have an array and a cell array with the same dimensions: A is a 1x2492 double array, and B is an 1x2492 cell cell array. I want to make a new cell array that assigns the values in A to the corresponding column values of B. Here was my code:
for n = 1:numel(B)
newArray(n) = [A(n),B{n}(2)];
newCellArray{n} = newArray;
end
When I ran the code, I got the error 'Subscripted assignment dimension mismatch.'
I think it's because some cells in B have multiple columns, and the code loop doesn't recognize that I want to assign the same value of A to all values in the cell.
For example, if cell 1 of B contains:
2 2355
23 1293
37 1222
I would like my code loop to assign the corresponding first value of A to 2355, 1293, and 1222. So basically, I'd like to have a new cell like this:
1 2355
1 1293
1 1222
I realize that this is a very confusing explanation, but I hope that it makes sense. Any and all help would be greatly appreciated - thank you very much!

I am not really sure what you are trying to do, but the code below will assign the value of A(ii) to every element in the first column of B{ii}. I am just saying this based on your example, but your explanation is really unclear..
C = B;
for ii=1:numel(C)
C{ii}(:,1)=A(ii);
end
And you are getting an error on newArray(n) = [A(n),B{n}(2)]; because you are trying to assign a vector to a singleton dimension. Try a(1) = [1 2] and you will still get an error, and this is independent on what your cell dimensions are, etc.. a(1,:)=[1 2], however, might work if the 2nd dimension of a is 2.

Try:
newCellArray = cell(numel(B),2);
for n = 1:numel(B)
lenB = length(B{n}(2));
newA = repmat(A(n),lenB);
newArray = [newA,B{n}(2)];
newCellArray = [newCellArray; newArray];
end

Related

Matlab loop to assign rows to cell array

I have a big cell array A=cell(a,b,c,d) and a row vector B with dimensions 1-by-b.
I want to build a loop in MATLAB that does the following:
for i=1:n
B = Calculate_row(input1,input2) %this is a function that creates my B row
A{a,:,c,i} = B(:)
end
anyway if I try to do A{a,:,c} = B(:) I receive the following error:
Expected one output from a curly brace or dot indexing expression, but there were b results.
And if I try to do A(a,:,c) = B(:) I receive the following error:
Conversion to cell from double is not possible.
Is there a way to do this? (I know a less elegant way that probably works would be to assign each value to the cell separately, but I would prefer not to do it).
One way to do this is to make B a cell array and then take advantage of comma-separated-lists:
B_cell = num2cell(B);
[A{a,:,c}] = B_cell{:} %// or [A{a,:,c,i}] = B_cell{:} if tim's comment is correct
Have a look at Loren Shure's article Deal or No Deal and also this answer for more.
The problem with your syntax, A{a,:,c} = B(:), is that the RHS (i.e. B(:)) is just one single matrix whereas the LHS is a comma-separated-list of b results. So you are basically requesting that 1 output be assigned to b variables and MATLAB doesn't like that, also hence the error message.
The problem with A(a,:,c) = B(:) is that indexing a cell array with () returns a cell array and you can't just assign a matrix (i.e. B(:)) to a cell array hence you second error.

How do I reassign even and odd indices of a character array into a new smaller character array in Matlab?

In matlab I have a 32x1 character array A such that
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6' ... 'F32'};
A = A';
Now I am trying to do the following with A.
For every even index of A meaning
A{2}, A{4}, A{6}...
I want to assign those values to a 16x1 character array B and for the odd indices of A I want to assign those values to a different 16x1 array C.
I use the following code:
for i=1:32
if mod(i,2)==0
B{i} = A{i};
else
C{i} = A{i};
end
end
and it works, but only partially because it assigns the right values at for e.g. B{2} and B{4} but the values in B{1} and B{3} are the same as in B{2} and B{4}.
Can anybody tell me how to reassign even and odd indices of a character array into a new smaller character array? My problem is that I am going from a 32x1 into a 16x1 and I'm not sure how to avoid the extra 16 entries.
Many thanks!
To get this question actual answered, use the idea of Luis Mendo in the comments. You can combine it with deal to save one line of code:
[B, C] = deal(A(2:2:end), A(1:2:end))
To make your loop work, you need a second running index jj:
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6'};
for ii = 1:6
jj = ceil(ii/2);
if mod(ii,2)==0
B{jj} = A{ii};
else
C{jj} = A{ii};
end
end

How do I use matlab ismember in data structures with multiple nested fields?

In matlab I have the following 2 data structures b and c defined as follows.
b(1).b = struct('c',{'a', 'b', 'c'})
c(1).b = struct('c',{'b', 'a', 'c'})
Now I want to use ismember to find out if the elements of b(1).b.c are contained in c(1).b.c and if so, which indices of c(1).b.c each of the elements belong to.
For example: b(1).b(1).c = a, I want to backtrace this to structure c to find which index of structure c 'a' belongs to (it should return 2 since 'a' is the second element of structure c).
I have tried
[~, ind] = ismember({b(1).b.c},{c(1).b.c})
which has worked for me previously with a different data structure but I now receive the following error:
*Error using cell/ismember>cellismemberR2012a (line 192)
Input A of class cell and input B of class cell must be cell arrays of strings, unless one is a string.
Error in cell/ismember (line 56)
[varargout{1:max(1,nargout)}] = cellismemberR2012a(A,B);*
I am not sure why its not working. Does anybody know how to fix this?
Thanks.
Googling around did not show any possible solutions but there are couple options:
[~, ind] = ismember([{b(1).b.c}],[{c(1).b.c}])
and casting to cell array:
[~,idx]=ismember(struct2cell(b(1).b),struct2cell(c(1).b))
idx=reshape(idx,1,3);
For both output should be:
2 1 3
I found the following to work.
First assigning b(1).b.c to an array S and then comparing that with the data structure c using ismember.
S = [b(1).b.c]
S = S'
[~, ind] = ismember(S,{c(1).b.c})
I have found this to work.
Also,
[~, ind] = ismember([b(1).b.c}],[c(1).b.c])
does not give an error but all the values in ind are zero which is not true for the data.
Thanks all for your input!

Matlab replacing 0 with empty cell in Cell array

I have a 10,000 x 65 Cell with 0's and 1's so for example if I type
C(1,1) I get [0] returned or likewise C(3,4) a [1] is returned
I need a way to turn every 0 into a blank cell and every 1 into a char t
I've tried the following with little success
[rows, cols] = size(M);
for i = 1:rows
for j = 1:cols
if strcmp(M(i,j), 1)
M(i,j) = 't';
end
end
end
It returns the same thing, I'm guessing its not recognising the 1's as strings. Any idea sort of simply doing the conversion straight in Excel.
thanks
You are not accessing the cell data-structure correctly.
First of all, if M really is a cell array, you will have to use M{i,j} to access the data.
What M(i,j)does is just create a sub-cell-array, which contains M{i,j} as entry.
Also strcmp isn't used correctly, if your cell array contains strings you should use strcmp(M{i,j}, '1').
If your cell array on the other hand contains integers, you would have to use: M{i,j}==1.

Concatenating 1D matrices of different sizes

I perhaps am going about this wrong, but I have data{1}, data{2}...data{i}. Within each, I have .type1, .type2.... .typeN. The arrays are different lengths, so horizontal concatenation does not work.
For simplicity sake
>> data{1}.type1
ans =
1
2
3
>> data{2}.type1
ans =
2
4
5
6
Results should be [1;2;3;2;4;5;6]
I've been trying to loop it but not sure how? I will have a variable number of files (a,b..). How do I go about looping and concatenating? Ultimately I need a 1xN array of all of this..
My working code, thanks..figured it out..
for i = 1:Types
currentType = nTypes{i}
allData.(currentType)=[];
for j = 1:nData
allData.(currentType) = [allData.(currentType); data{j}.(currentType)(:,3)]; %3rd column
end
end
Look at cat, the first argument is the dimension. In your simple example it would be:
result = cat(1,a,b);
Which is equivalent to:
result = [a;b];
Or you can concatenate them as row vectors and transpose back to a column vector:
result = [a',b']';
For the case of a structure inside a cell array I don't think there will be any way around looping. Let's say you have a cell array with M elements and N "types" as the structure fields for each element. You could do:
M=length(data);
newData=struct;
for i=1:M
for j=1:N
field=sprintf('type%d',j); % //field name
if (M==1), newData.(field)=[]; end % //if this is a new field, create it
newData.(field)=[newData.(field);data{i}.(field)];
end
end

Resources