MATLAB Matlab: dynamic data entry into structure

AI Thread Summary
The discussion revolves around dynamically adding data to a structure in MATLAB for monitoring plant growth without requiring user input for iteration numbers. The user seeks a method to automatically append new data to existing matrices within the structure while ensuring that no data is overwritten. Suggestions include using the `numel` function to determine the current number of entries and appending new data directly to the structure fields. A working solution was shared that checks if data for a specific plant has been entered previously, allowing for seamless data entry. Overall, the conversation emphasizes improving code efficiency and reducing user error in data input.
craigpmorgan
Messages
8
Reaction score
0
Hi all,

I've created a structure containing various fields of data. The data in these fields is stored in matrices and is be added to at regular intervals. I'd like the system to identify the amount of inputs the fields already contain and then extend said matrices to include this new data.

The program concerns the monitoring of plant growth.
The code below works fine but requires the user to know the amount of measurements that have already been input. I'd like to avoid this as it could easily lead to data being overwritten:id = input('Enter plant number: ');
iteration = input('Enter iteration: ');

plant(id).entryDate(iteration) = {date};
plant(id).height(iteration) = [height]; % The variable height is already in the workspace

My idea for ensuring new data is stored in the correct place was to use numel function, something like the following (removing the user-input value of 'it' from above):

previous_iterations = numel(plant(id).height);
it = previous_iterations + 1;

I can't this this or anything similar to work.

Thanks very much for your time, I'd greatly appreciate any help.
Craig
 
Last edited:
Physics news on Phys.org
do you mean for each field, how many elements they contain?

that's simply:

size(plant(id).matrixofinterest)

where matrixofinterest is the field you want a size for.
 
Hi Pythagorean,

I can find the number of elements within the matrix of a particular field using either the numel or the size functions. However, I'm not sure of the syntax that checks the size of the existing matrix (via one of the functions mentioned) and makes the incoming data an extension of it. I require something like the following. I have now achieved what I require using a loop but I'm convinced there's a more elegant solution.

id = input('Enter plant number: ');

previous_iterations = numel(plant(id).height);
iteration = previous_iterations + 1;
plant(id).entryDate(iteration) = {date};
plant(id).height(iteration) = [height]; % The variable height is already in the workspace

As I said, I have now got the program to work with an if statement but if anyone knows how to make the above (or similar) work I would be grateful.

Thanks again,
Craig
 
id = input('Enter plant number: ');

previous_iterations = numel(plant(id).height);
iteration = previous_iterations + 1;
plant(id).entryDate(iteration) = {date};
plant(id).height(iteration) = [height]; % The variable height is already in the workspace

Ok, I think I understand what you mean. In general, you can assign x with an appended row/column/element like:

x = [x new_value]

that is, make x the old x with an additional value called "new_value"


Applied to your problem:

plant(id).entryDate(iteration) = [plant(id).entryDate(iteration) {date}];
plant(id).height(iteration) = [plant(id).height(iteration) height]



I'm not sure how your data entry is going though. You shouldn't need a for loop if you're just doing this every time you get a new entry. If you're adding batch entries, then you CAN add all entries at once:

x = [x x_new] where x_new is now a vector of the new entries (rather than entering them one at a time).

so if x = [1 2 3]

and I go

x = [x [4 5 6]]

I'll get:

x = [1 2 3 4 5 6];

is that helpful in your implementation?

You may just need to run me through the the overall goal and the general order of operations if I'm still missing the mark.
 
Also, if you have a predetermined number of entrees, we can make it a bit more efficient, depending on the sizes you're working with, by preallocating the matrices in the structure.
 
Hi,

The code you've written doesn't quite apply to this problem, though it works if the user manually inputs the iteration number.

My issue is that I don't want the user to have to specify the iteration before the data is stored, which means that the structure 'plant' needs to be previously defined. However, if no data for 'plant x' has not been entered previously, the instance of the structure plant(x) does not yet exist. The following code works, I'm happy to leave it as is, since this problem seems more awkward than I realized!

% STORES DATA IN CORRECT PLACE WITHOUT THE NEED TO INPUT ITERATION

avgHeight = 22; % In the actual program these variables will be
avgVol = 33; % present in the workspace and are used here just
% testing.

id = input('Enter ID: ');
XX = 2;
while XX ~= 1; % Variable XX used to ensure valid input
q = input('Has any data for this plant been entered previously? ','s');

if q == 'y' | q == 'Y' % Since data has been entered previously,
id = input('Enter ID: '); % plant(id) already exists and can be
it = numel(plant(id).height); % added to.
next = it + 1;

plant(id).date(next) = {date};
plant(id).height(next) = [avgHeight];
plant(id).volume(next) = [avgVol];
plant(id)
XX = 1;
elseif q == 'n' | q == 'N' % Since plant is new, plant(id) is created
next = 1; % and the variables are each stored in the
% first position of each field.

plant(id).date(next) = {date};
plant(id).height(next) = [avgHeight];
plant(id).volume(next) = [avgVol];
plant(id)
XX = 1;

else
disp(sprintf('\nThis input is not valid. Please answer Y/N.'));

end
end

As I said, this code now does what I need but seems overly messy.
Thanks for the help
 
the code i wrote does not require knowledge of iterations. It merely appends the latest entry to the end of an already established array. For instance, you could type:

a = [];

a = [a 5];
a = [a 3];

and you will now have:

a = [5 3];

note that 5 and 3 are actual entries, not number of iterations or anything, you're building up a one element at a time.

However, if no data for 'plant x' has not been entered previously, the instance of the structure plant(x) does not yet exist.

and speaking of exist... try 'help exist' rather than requiring user input. This avoid user error and reduces seconds per entry spent answering the input.
 

Similar threads

Replies
1
Views
9K
Replies
12
Views
3K
Replies
3
Views
3K
Replies
4
Views
5K
Replies
2
Views
5K
Replies
10
Views
3K
Back
Top