Convert struct to cell or matrix? - arrays

I have a struct array imported from a tab file, with 100+ name\double rows. The first row has a character value (name\char). I'm trying to load this as a matrix and converted it to cells, removing the top row entirely.
But when I use cell2mat(array), it has the error:
All contents of the input cell array must be of the same data type.
I know this is from the Names vs. double columns. But is there a way to convert this to a matrix? Or, if the data is rows of
name | 1000x1 double
is it better just to leave this as a cell array?

It's not possible to have a matrix containing both strings and numeric values. If you want something like that, cell array is your only option. But, it will be very limiting if you want to process the numeric values using matrix/vector operations, or functions that expect matrices/vectors as input. One option would be to store the strings and numeric data separately; keep the strings in a cell array S and the numeric data in a matrix M. Then, keep track of the elements. For example, S{i} and row M(i, :) could both correspond to entry i from your original table. Another option would be to make your own data structure using struct(), which can contain both strings and numeric values.

Related

Excel array formula - managing data in table with dynamic height

I have a working array formula, which creates a list of values in column A. The length of the list depends on the input values of the formula and will vary over time. Values could be removed and added anywhere in the list, not necessarily at the end. Now in column B I want to manually add comments on the values in column A. When the length of the list changes, the values in column B don't move along with the values in column A, so they are not longer on the correct line. Is there a way to solve this?
You can try to use the OFFSET function for the dynamic variable.

How to use a string from a single cell as an array in a function without VBA

How do I convert a string from a cell to a text array inside of a function, that should use the array, without using VBA and without adding the array into any other part of the document? It will be one of these arrays on more than 1000 rows. The string format is ^[a-zA-Z0-9.,-]*$ with "," as delimiter.
This is the functionality I would like to achieve
I have an excel table with the following columns
A: ID numbers to compare, separated by comma (delimiter can be changed if needed). About 100 ID's would be good to support at least.
B: ID (Each value on the rows in the column are unique but not sorted and can't be sorted because sorting is needed based on other criterias)
C: Value (Several rows in the column can have the same value)
D: Output the one ID of the comma separated ID's that has the highest value on its row
The problem part of the output
So far I have made a function which find the correct ID in column B based on the values in column C but only if I enter the string from column A as an array constant manually within the function. I have not managed to get the function to create the array itself from column A, which is required.
Working part of the code
In this code I have entered the values from column A manually and this is working as it should.
=INDEX({"1.01-1","1.01-3","1.08-1","1.01-1-1A"},MATCH(MAX(INDEX(C$10:C$20,N(IF(1,MATCH({"1.01-1","1.01-3","1.08-1","1.01-1-1A"},B$10:B$20,0))))),INDEX(C$10:C$20,N(IF(1,MATCH({"1.01-1","1.01-3","1.08-1","1.01-1-1A"},B$10:B$20,0)))),0))
Note that the start row is not the first row and the array is used 3 times in the function.
Code to try to convert the string to a text array
Not working but if wrapped in SUMPRODUCT() it provide an array to the SUMPRODUCT() function, of course not usable since I then can't pass on the array. The background to this code can be found in question Split a string (cell) in Excel without VBA (e.g. for array formula)!.
=TRIM(MID(SUBSTITUTE(A10,",",REPT(" ",99)),(ROW(OFFSET($A$1,,,LEN(A10)-LEN(SUBSTITUTE(A10,",",""))+1))-1)*99+((ROW(OFFSET($A$1,,,LEN(A10)-LEN(SUBSTITUTE(A10,",",""))+1)))=1),99))
The second code output the first item of the array and inserted in the first code do not change this result as it did when wrapping the second code in SUMPRODUCT().
Here is a picture of my simplified test setup in Excel for this case, identical to what is described above.
Simplified test setup
I'm not really sure what you are doing with your formula.
But to convert contents of a cell to a comma separated text array to be used as the array argument to the INDEX or MATCH functions, you can use the FILTERXML function. You'll need to educate yourself about XML and XPATH to understand what's going on, but there are plenty of web resource for this.
For example, with
A10: "1.01-1","1.01-3","1.08-1","1.01-1-1A"
The formula below will return 1.08-1. Note the 3 for the row argument to the INDEX function.
=INDEX(FILTERXML("<t><s>" & SUBSTITUTE(SUBSTITUTE(A10,"""",""), ",", "</s><s>") & "</s></t>", "//s"),3)

Retrieving data from table using cell array - Matlab

I have a table in Matlab crsp and and cell array of numbers that serve as keys. I want to retrieve information from the table using that cell array which is stored as a variable. My code is as follows:
function y = generateWeights(permno_vector, this_datenum, crsp)
crsp(crsp.PERMNO == permno_vector,:);
crsp is defined as a table while permno_vector is the cell array. It contains a couple permnos that are used to retrieve information.
In this case, my code is not working and will not allow me to access the values in crsp. How do we access table values using a vector array?
As James Johnstone points out, the first problem with the code you've posted is that it doesn't assign anything to y, so as written your function doesn't return a value. Once you've fixed that, I assume the error you are seeing is Undefined operator '==' for input arguments of type 'cell'. It's always helpful to include this sort of detail when asking a question.
The syntax
crsp(crsp.PERMNO == x,:)
would return those rows of crsp that had PERMNO equal to x. However if you want to supply a list of possible values, and get back all the rows of your table where your target variable matches one of the values in the list, you need to use ismember:
crsp(ismember(crsp.PERMNO, cell2mat(permno_vector)),:)
if permno_vector is a cell array, or simply:
crsp(ismember(crsp.PERMNO, permno_vector),:)
if you can instead supply permno_vector as a numeric vector (assuming of course the data in crsp.PERMNO is also numeric).

How can I fill an Excel array without using VBA?

I have data in the format (Observed value, Number of observations) and would like to convert it to an array of values. For example, if I had (Value = 12, Number of observations = 3), I would like to use built-in formulas to create 3 cells each containing the number 12. Is this possible? This is an example of what I'm trying to do. Thanks!
If you're willing to accept empty string instead of blank then, assuming your first column of inputs are in A1:A2, fill your output range for column A starting from A4 with:
=IF(ROW()-ROW(A$4)<A$2,A$1,"")
You can avoid the reference to the top cell by using:
=IF(ROW()-MIN(ROW())<A$2,A$1,"")
Make it an array formula (Ctrl+Shift+Enter) in the output range of column A.
You can copy either of these to the right to support additional columns.

Convert one one column to timestamp in cell array MATLAB

I have a cell array in MATLAB that has the following columns..
Timestamp Info Joint X Y Z State
0.4449 'BASE05' 'SpineBase' -0.4222 -0.5245 2.681 'Tracked'
The 0.4449 needs to be converted to a timestamp format which I have so far been achieving by extracting column 1 and performing datestr on.
time = num(:,1);
time = num2cell(time);
Bodytime = datestr(cell2mat(time), 'HH:MM:SS');
This gives me a character array with all the timestamps.
However, I need to put this character array back into the first column of cell array. I'm having some trouble here, I was trying to convert my cell array to character array but as I have a mix of numbers and string I don't think that's the way forward. I also tried to replace the first column from the bodytime character array into my original cell array BodyData, but I don't think that's the way forward either.
Ideally I need to get something like this
Timestamp Info Joint X Y Z State
10:44:59 'BASE05' 'SpineBase' -0.4222 -0.5245 2.681 'Tracked'
My main goal here is to look up a certain timestamp of when an event happened and extract/plot (tbd) all the relative information for that time.
When you call datestr with an array of timestamps, what you are actually getting back is a "matrix" of characters, where each row is in the format HH:MM:SS. There is no greater separation between the rows of this matrix than there is between the columns of it (where column 3, for example, is the first : character of each timestamp).
You can certainly split this array back into a cell array, where each cell element is a single timestamp, which can then go back into your source cell array. To do this use mat2cell:
BodytimeCell = mat2cell(Bodytime,size(time));
However there is probably unnecessary complexity in what you've already done. Most simply, if your aim is a cell array of timestamp strings, you could do this directly with cellfun:
BodytimeCell = cellfun(#(t) datestr(t, 'HH:MM:SS'), time, 'UniformOutput',false);
However you might also consider if it really helps to store the timestamps as a strings at all. It may be more advantageous to store them as a datetime array, which can remember the format you want to display it in while still allowing you to work with the value numerically if you need to.
The structure of the data as a whole also suggests it may be better to store as a table than a cell array. This gives you more natural ways to interact with the data - for example, the numeric columns in a table can be treated like numeric arrays directly, rather than having to convert from a cell array of numbers.

Resources