I have an array that I want to basically capture as text so I can write it to one cell of an Excel file as a column header. It's a range of subjects, and I'll have some data underneath. So the range is:
range = 2:12;
which creates and array, but I want the Excel file header to just read 2:12. I've tried creating another variable to capture this text in one field, using num2str like this:
rangeChar = num2str(range);
and I get:
rangeChar = 2 3 4 5 6 7 8 9 10 11 12
but they are each separate fields, so when exported to Excel they each take up their own cell. The original range is not always sequential - for example I might have
range = cat(2, 2:4, 8, 9:12);
so I can't just do a
rangeChar = sprintf('%d:%d', range(1), range(end));
type of thing either. Any thoughts?
You can do it the other way around and keep the range in the string and extract the vector from that when you need it:
rangeChar = '2:12';
range = eval(rangeChar);
Couldn't you just write :
range = '2:12';
Use a cell array to hold "range" and use the following code :
range = {2:4, 8, 9:12};
range_str=repmat({''}, size(range));
for i=1:length(range)
if length(range{i})==1
range_str{i}=sprintf('%d', range{i});
else
range_str{i}=sprintf('%d:%d', range{i}(1), range{i}(end));
end
end
range_str
Output :
range_str =
'2:4' '8' '9:12'
Related
I'm trying to find values in a multidimensional array which are only in one column. I can find the correct values when searching the entire multidimensional array. But if I try and limit the find in the multidimensional array to say just the second column the values are not the expected ones.
example of code and correct output:
A = [2 4 6; 8 10 12]
A(:,:,2) = [5 7 9; 11 13 15]
A(:,:,3) = [55 4 55; 167 167 154]
[row,col,page]=ind2sub(size(A), find(A(:,1,:)==4))
row =1,1
col =2,2
page =1,3
But If I try and limit the find to just the second column using these commands
[row,col,page]=ind2sub(size(A), find(A(:,2,:)==4))
row =1,1
col =1,3
page =1,1
I get values that are different from the expected ones. I'm trying to limit the multidimensional find to search all pages, all rows, and one specific column. The output should be the same as the first example. How can I fix this?
With [m,n,o]=size(A), you are using A(:,2,:)==4 which is a matrix n*1*o. ind2sub expects a n*m*o matrix. Typical approach is using a mask:
mask=false(size(A));
mask(:,2,:)=true;
[i,j,k]=ind2sub(size(A), find((A(:,:,:)==4)&mask))
The mask selects the entries you are interested in.
Daniel's answer works by defining a mask and then searching throughout the whole array with that mask applied. The following limits the search to the desired column, and thus may be faster for large arrays:
col = 2; %// desired column
[row, page] = ind2sub([size(A,1) size(A,3)], find(A(:,col,:)==4));
If you need col as a vector the same size as row and page, you can of course achieve it with col = repmat(col,size(row)).
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
I need to parse a .txt file in Matlab so that all lines of the file are a different element in an array. Each element of the array would also be an array of integers. So I need to make an array of arrays from a .txt file.
The problem I'm having is that I can't figure out which function to use to parse the file. If I use importdata(filename), it only parses the first line of the file. If I use textscan, it parses the file in colums, and the file is formatted like:
1 1 1 1 1
13 13 13 13 13
2 2 2 2 2
14 14 14 14 14
I need each of the rows to be an array that I can then use to compare my data against.
Is there an option for either one of those functions that would work for my purposes? I've tried looking on the MATLAB documentation, but can't make sense of it.
If each array needs to be a different size, you need to use a cell array to contain them. Something like this:
fid = fopen('test.txt'); %opens the file
tline = fgets(fid); % reads in the first line
data = {}; % creates an empty cell array
index = 1; % initializes index
while ischar(tline) % loops while the line that has just been read contains characters, that is, the end of the file has not been reached.
data{index} = str2num(tline); % converts the line that has just been read in to a string and assigns it to the current column of data
tline = fgets(fid); % reads in the next line
index = index + 1; % increments index
end
fclose(fid);
If you know your data will have the specific format of 5 numbers followed by a single number, you can use dlmread and then format the resulting matrix.
data = dlmread('data.txt',' ');
multipleValueRows = data(1:2:end,:);
singleValueRows = data(2:2:end,1);
The data matrix has the size (number of rows of your file) x 5 columns. In the rows where you only have a single number, the data matrix will contain zeros in columns 2-5.
I need to get a value which has the maximum number of occurrences in the unique data set from a big column based on a condition. I just need one value and not the array.
See below the example data that I am working with. I have done it in MATLAB but want to know it in Excel.
So in the above data for example, I want to get the unique values for lanes based on the value of #safea. So if #safea=102 then unique values of lanes=(2,3,1). But I want the value from these set of data which has maximum number of occurrences. In this case it is 2 because 2 has come up 5 times whereas 3 has come up once and 1 has come up as only 1 time.
Another example:
If I select #safea as 162, then the number of unique values in lanes (5 and 4) but 5 has come up 4 times and 4 has come up as only 1 time so the final answer that I want is '5'.
If you don't mind using VBA, I've devised a Function you can use for what you want. Given the #safea values are in column A and the lane values are in column B, you can use this:
Function MODEIF(criteria As Integer) As Integer
Dim count As Integer
count = Application.WorksheetFunction.CountA(Range("A:A"))
Dim list() As Integer
Dim size As Integer
size = 0
Do While count > 0
If (Range("A" & count) = criteria) Then
ReDim Preserve list(size)
list(size) = Range("B" & count)
size = size + 1
End If
count = count - 1
Loop
MODEIF = Application.WorksheetFunction.Mode(list)
End Function
Just put this Function in a Module, go to the spreadsheet, and type =MODEIF(102) or whatever #safea value you want the mode for and it will give you the answer.
You could also use this worksheet function to get a conditional MODE:
=MODE(IF(**your #safea value here**=$A$2:$A$22,$B$2:$B$22))
This is an array formula. Confirm entry by pressing Ctrl+Shift+Enter (not just Enter).
I have a problem when using cell arrays in an m-file. I create a number of cell arrays using the function given in here. What I store on each of these arrays is numerical values being read from a text file (I convert them to string before I put them into the arrays). The problem is that the some numbers doesn't seem to be strored in the arrays correctly:
The text file contains that:
1976787196
8
1976945848
8
1977105448
8
And the contents of a cell array in which the above is store are the following:
Columns 1 through 3
1976787196 681405151445000 1976945848
Columns 4 through 6
685476780441608 1977105448 685476780441608
As you can see, instead of stroring 8, I get a very big integer.
Actually, I want all the contents of the cell arrays that I create to contain only 32-bit integers. Can I specify that requirement somehow? Thanks in advance!
It depends how you read the data from text file. Try using TEXTSCAN function. Format string '%u32' specifies that you want to read unsigned 32-bit integer data.
filename = 'test.txt';
fid = fopen(filename,'r');
x = textscan(fid,'%u32','delimiter','\t','CollectOutput',1);
x = x{1};
fclose(fid);