Reputation: 225
I have a data set with multiple fields of which several of the fields are different names for equivalent properties. I have rescaled and adjusted the data so that the quantities are comparable and want to merge them into a single field.
As a toy example, let's say I have:
s = struct('pounds', [nan nan 4.8], 'pennies', [120 370 nan]);
s.pennies = s.pennies/100;
How do I merge my incomplete fields to get the desired output:
snew = struct(pounds, [1.2 3.7 4.8]);
Upvotes: 1
Views: 62
Reputation: 1544
try my two-liner below
c=struct2cell(s);
s=struct('pounds',unique([c{:}]));
even better, you can also do it using the below oneliner
s=struct('pounds',unique(cell2mat(cellfun(@(x) x(:), struct2cell(s),'UniformOutput',false)))')
Upvotes: 0
Reputation: 112759
The following works for any number of fields. Since it is guaranteed that only one field is not NaN
at each position, you can
NaN
's. By assumption, this gives exactly one number per column.s = struct('pounds',[nan,nan,4.8], 'pennies', [120,370,nan])
s.pennies = s.pennies/100; % example data
target_field = 'pounds'; % field to which the conversion has been done
t = struct2cell(s); % convert struct to cell array
t = vertcat(t{:}); % convert cell array to matrix
t = t(~isnan(t)).'; % keep only numbers, ignoring NaN's
result = struct(target_field, t); % arrange into a struct
Upvotes: 1
Reputation: 125874
If you have modified your field values such that they should be equivalent, and simply need to combine the non-NaN
values, one option is to vertically concatenate the fields then use min
or max
down each column (which will ignore the NaN
values). Then just remove the unwanted field with rmfield
:
>> s = struct('pounds', [nan,nan,4.8], 'pennies', [120,370,nan]);
>> s.pounds = min([s.pounds; s.pennies./100], [], 1); % Scaling included here
>> s = rmfield(s, 'pennies')
s =
struct with fields:
pounds: [1.2000 3.7000 4.8000]
Upvotes: 2