help with getfield command

Dear Guys,
I am using the getfield command to extract data from the struct i have created. The struct is 1 by 4 with 8 fields.
I firstly used the getfield command to give back the first data reference in the struct:
for i = 1:4
a(:,i) = getfield(stocks,'Close');
end
this provided a matrix with 4 columns with the same data. I then tried to change the getfield command to get the other 3 data references in the struct for this field:
for i = 1:4
a(:,i) = getfield(stocks,{i,4},'Close');
end
but receive an error Subscripted assignment dimension mismatch
would it be possible to have all four data references from the struct using a for loop?

Answers (1)

In the above, you state that The struct is 1 by 4.. which implies that stocks is a 1x4 array of (stock) structs. If that is the case, then you can access each stock simply by stock(i). And so your code becomes
for k = 1:4
a(:,k) = getfield(stocks(k),'Close');
end
(Note that I replaced i with k to avoid confusion with the imaginary number representation of i.)

11 Comments

thanks for the idea, i gave this a go but it returned back a mismatch error message
for k = 1:4
a(:,k) = getfield(stocks(k),'Close');
end
Subscripted assignment dimension mismatch.
is there another way to select all the data for each field
What are the dimensions of a? Is that something that you have already defined? At the very least, it must have 4 columns.
Prior to running the above code, in the Command Window, type
size(stocks)
size(a)
to see what are the dimensions of these two objects.
a is defined and linked to the field data in the struct. It has the same number of columns as the number of rows in the struct (4) and the rows vary for each column in a
when i execute the first for loop a's dimensions are : 7173*4 meaning that only one row in the struct has been transferred over four times when there should be a different one for each column.
size of stocks is 1*4 struct size(stocks)
ans =
1 4
Matthew - I don't understand what you mean by It has the same number of columns as the number of rows in the struct (4) and the rows vary for each column in a. How can the rows vary for each column in a? Is a a cell array? Where does 7173 come from?
the struct is essentially a table with 8 fields and 4 rows, each row is like a type of stock. a needs to be a matrix of one field taken from the table that has 4 rows each containing data that are approximately 7000+ rows by 1 column.
so a uses the rows in the table and when in matrix format becomes a column inside it.
the 7173 is the length(rows) of the values in the table for one stock
I have modified the for loop and it now produces four columns but overwrites the initial three columns with zeros and outputs the fourth column with correct data from the table; below is the code:
for i = 1:4 z = []; z(:,i) = getfield(stocks,{1,i},'Close'); end
not sure where it's going wrong in not retaining the first three column data
The problem is that on each iteration of the for loop, the z matrix is reset to the empty matrix
for i = 1:4
z = [];
% etc
Execute the z=[]; statement before the for loop is executed. Even better, if you know the length of stocks(i).Close, then use this information to pre-allcate memory to z
z = zeros(length(stocks(1).Close),4);
i tried to execute the z =[] before the for loop and received a subscripted assignment dimension mismatch error:
z = []; for i = 1:4 z(:,i) = getfield(stocks,{1,i},'Close'); end Subscripted assignment dimension mismatch.
However, I used the last suggestion and this accepted the code without any issues but received the same problem only populating the last column with correct data and the first three with zeros:
for i = 1:4 z = zeros(length(stocks(i).Close),4); z(:,i) = getfield(stocks,{1,i},'Close'); end
Since there are only four iterations of the loop, I suggest you step through the code in the debugger. I suspect that what may be happening is that you have some rows longer (or shorter) than others and so on the first iteration the matrix is sized for a particular row length but on the second iteration, more data is trying to be "fitted" into that matrix.
Try the following as before which will only save the last column
for k = 1:4
z = [];
z(:,k) = getfield(stocks,{1,k},'Close');
fprintf('length=%d\n',length(z));
end
The above will print out the length of z on each iteration. If the length is different for each k then you will not be able to fit each column of data into the same matrix. That is fine - you can use a cell array instead:
z = cell(4,1);
for k = 1:4
z{k} = getfield(stocks,{1,k},'Close');
end
Try the above and see what happens.
thanks the second part assigning z to be a 4by1 cell gave back : z = cell(4,1); for k = 1:4 z{k} = getfield(stocks,{1,k},'Close'); end z = transpose(z); z =
[7173x1 double] [6974x1 double] [7042x1 double] [7040x1 double]
but would there be a way to get the values in the cells to show the output, i've tried allsorts of commands but none reveal the contents
z{1} would return the 7173 elements for column 1; z{2} the 6974 elements for column 2, etc.
Note that it is because each column has a different number of elements (with the exception of the last two) that we got the subscripted assignment dimension mismatch error.

Sign in to comment.

Categories

Asked:

on 8 Jul 2014

Commented:

on 10 Jul 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!