I have a cell vector with labels, and an array with some values. The cell vector is 3x1 and the array is 3x4. I want to join these two things into a table (3x5). Below a minimum working example with what I tried (which of course did not work):
label{1,1} = 'A';
label{2,1} = 'B';
label{3,1} = 'C';
Matrix = rand(3,4);
Table = [cell2table(label), array2table(Matrix)]
Related
I have a two-index MATLAB Cell Array (AllData{1:12,1:400}) where each element is a structure. I would like to extract a list of values from this structure.
For example, I would like to do something like this to obtain a list of 12 values from this structure
MaxList = AllData{1:12,1}.MaxVal;
This comes up with an error
Expected one output from a curly brace or dot indexing expression, but there were 12 results
I can do this as a loop, but would prefer to vectorize:
clear MaxList
for i=1:12
MaxList(i) = AllData{i,1}.MaxVal;
end
How do I vectorize this?
If all structs are scalar and have the same fields, it's better to avoid the cell array and directly use a struct array. For example,
clear AllData
AllData(1,1).MaxVal = 10;
AllData(1,2).MaxVal = 11;
AllData(2,1).MaxVal = 12;
AllData(2,2).MaxVal = 13;
[AllData(:).OtherField] = deal('abc');
defines a 2×2 struct array. Then, what you want can be done simply as
result = [AllData(:,1).MaxVal];
If you really need a cell array of scalar structs, such as
clear AllData
AllData{1,1} = struct('MaxVal', 10, 'OtherField', 'abc');
AllData{1,2} = struct('MaxVal', 11, 'OtherField', 'abc');
AllData{2,1} = struct('MaxVal', 12, 'OtherField', 'abc');
AllData{2,2} = struct('MaxVal', 13, 'OtherField', 'abc');
you can use these two steps:
tmp = [AllData{:,1}];
result = [tmp.MaxVal];
Using the answer above as a starting point, it is also possible to extract a 2d array of vectors from the Cell Array Structure. In each element of the 2d AllData cell array is a 2048 element vector called DataSet. The following commands will extract all of these vectors to a 2d array:
tmp = [AllData{:,1}];
len = length(tmp(1).DataSet); % Gets the length of one vector of DataSet
tmp2 = [tmp.DataSet]; % Extracts all vectors to a large 1-d array
AllDataSets = reshape(tmp2,len,[])'; % Reshapes into a 2d array of vectors
I have a 1-by-4 cell array, D. Each of the cell elements contains 2-by-2 double matrices. I want to do random permutation over each matrix independently which in result I will have the same size cell array as D but its matrices' elements will be permuted and then the inverse in order to obtain the original D again.
for a single matrix case I have the code and it works well as follows:
A=rand(3,3)
p=randperm(numel(A));
A(:)=A(p)
[p1,ind]=sort(p);
A(:)=A(ind)
but it doesn't work for a cell array.
The simplest solution for you is to use a loop:
nd = numel(D);
D_permuted{1,nd} = [];
D_ind{1,nd} = [];
for d = 1:nd)
A=D{d};
p=randperm(numel(A));
A(:)=A(p)
[~,ind]=sort(p);
D_permuted{d} = A;
D_ind{d} = ind;
end
Assuming your D matrix is just a list of identically sized (e.g. 2-by-2) matrices, then you could avoid the loop by using a 3D double matrix instead of the cell-array.
For example if you hade a D like this:
n = 5;
D = repmat([1,3;2,4],1,1,n)*10 %// Example data
Then you can do the permutation like this
m = 2*2; %// Here m is the product of the dimensions of each matrix you want to shuffle
[~,I] = sort(rand(m,n)); %// This is just a trick to get the equivalent of a vectorized form of randperm as unfortunately randperm only accepts scalars
idx = reshape(I,2,2,n);
D_shuffled = D(idx);
In Matlab, at the end of three different for loops (for a=1:240,b=1:5 and c=1:3), I generate a {1,3} cell array where each cell contains a (1,5) array that reports only the last result of the 240 iterations.
How can I generate, apart of this cell array, a (240,5,3) 3d array that stores the result of each iteration?
Or, equivalently, a cell array that stores again the information and then convert it into a (240,5,3) 3d array?
The code would be along the lines of:
%// Size of the problem
Na = 240;
Nb = 5;
Nc = 3;
%// Allocate empty cell array
result = cell(Na, Nb, Nc);
%// Loop
for a = 1:Na
for b = 1:Nb
for c = 1:Nc
%// Here is the code for computing the
%// result x of the last iteration.
result{a,b,c} = x;
end;
end;
end;
I have a cell array with x columns, each with a yx1 cell. I would like to randomize the "rows" within the columns. That is, for each yx1 cell with elements a_1, a_2, ... a_y, I would like to apply the same permutation to the indices of a_i.
I've got a function that does this,
function[Oarray] = shuffleCellArray(Iarray);
len = length(Iarray{1});
width = length(Iarray);
perm = randperm(len);
Oarray=cell(width, 0);
for i=1:width;
for j=1:len;
Oarray{i}{j}=Iarray{i}{perm(j)};
end;
end;
but as you can see it's a bit ugly. Is there a more natural way to do this?
I realize that I'm probably using the wrong data type, but for legacy reasons I'd like to avoid switching. But, if the answer is "switch" then I guess that's the answer.
I'm assuming you have a cell array of column vectors, such as
Iarray = {(1:5).' (10:10:50).' (100:100:500).'};
In that case, you could do it this way:
ind = randperm(numel(Iarray{1})); %// random permutation
Oarray = cellfun(#(x) x(ind), Iarray, 'UniformOutput', 0); %// apply that permutation
%// to each "column"
Or converting to an intermediate matrix and then back to a cell array:
ind = randperm(numel(Iarray{1})); %// random permutation
x = cat(2,Iarray{:}); %// convert to matrix
Oarray = mat2cell(x(ind,:), size(x,1), ones(1,size(x,2))); %// apply permutation to rows
%// and convert back
I am currently working using matlab, I have uploaded a csv file into a cell array that I have named B. What I now wish to do is to input the information of B into a 3-D cell array, the 3rd dimension of the array being the first column of B which are strings ranging from "chr1" to "chr24". The full length of B is m, and the maximum length of any "chr" is maxlength. I doubt that this is the best way of going about it but here is my code:
for j = 1:m ,
Ind = findstr(B{1}{j}, 'chr');
Num = B{1}{j}(Ind+3:end-1);
cnum = str2num(Num);
for i = 1:24,
if cnum == i;
for k = 2:9 ,
for l = 1:maxlength ,
C{l}{k}{i} = B{k}{j};
C{l}{k}{i}
end
end
end
end
end
The 3-D array that comes out of this does not match the corresponding values in the initial array. I also want to know if this is the right way to create a 3-D array, I can't seem to find anything on the matlab website about them.
Thanks
There are a few possible issues with your approach: First of all, Matlab indexing is different from c-style indexing into tables. myCell{i}{j} is the j-th element of the cell array that is contained in the i-th element of the cell array myCell. If you want to index into a 2-d cell array, you would get the contents of the element in row i, column j as myCell{i,j}.
If the columns 2 through 9 of your .csv file contain all numeric data, it may be a lot more convenient to use either a 1D cell array with an entry for every chromosome, or to use a 2D or 3D numeric array if you get, for each chromosome, a single row, or a table, respectively.
Here's one way to do it
%# convert chromosomes to numbers
chromosomes = B{1};
chromosomes = strrep(chromosomes,'X',25);
chromosomes = strrep(chromosomes,'Y',26);
tmp = regexp(chromsomes,'chr(\d+)','tokens','once');
cnum = cellfun(#(x)str2double(x{1}),tmp);
%# catenate the rest of B into a 2D cell array
allNumbers = cell2mat(cat(2,B{2:end}));
%# now we can make a table with [chromosomeNumber,allOtherNumbers]
finalTable = [chromosomeNumber,allNumbers]
%# alternatively, if there are multiple entries for each chromosome, we can
%# group the data in a cell array, so that the i-th entry corresponds to chr.i
%# for readability, use a loop
outputCell = cell(26,1); %# assume 26 chromosomes
for i=1:26
outputCell{i} = allNumbers(cnum==i,:);
end
I've managed to do this with only two for loops, here is my code:
C = zeros(26,8,maxlength);
next = zeros(1,26);
for j = 1:m ,
Ind = findstr(B{1}{j}, 'chr');
Num = B{1}{j}(Ind+3:end-1);
cnum = str2num(Num);
if Num == 'X'
cnum = 25;
end
if Num == 'Y'
cnum = 26;
end
next(cnum) = next(cnum) + 1;
for k = 2:9 ,
D{cnum}{k-1}{next(cnum)} = B{k}{j};
C(cnum,k-1,next(cnum)) = str2num(B{k}{j});
end
end