0

I'm loading qxf data into MATLAB using the function qxf2mat. This creates the following 1x1 struct:

struct with fields:

                 qxfName: 'BSR1786214'
        numberOfChannels: 14
          numberOfCycles: 24477
          parameterCodes: {1×14 cell}
          parameterTitle: {1×14 cell}
     parameterShortTitle: {1×14 cell}
     parameterDefinition: {1×14 cell}
    minimumObservedValue: [1×14 double]
    maximumObservedValue: [1×14 double]
             absentValue: [1×14 double]
                datetime: [24477×20 char]
                BTVOLTCM: [1×24477 single]
          BTVOLTCM_flags: {1×24477 cell}
                HEADCM01: [1×24477 single]
          HEADCM01_flags: {1×24477 cell}
                ISCMBMA1: [1×24477 single]

What I want to do now is extract all the [1x24477 single] elements and put them into their own matrix. So the matrix would have 24477 rows, and in this example, 3 columns.

I've used struct2cell to convert the struct into a cell array, and was planning to use cell2mat after that, but I can't because of all the different data types.

4
  • Wouldn't be easier just to access them by name? Or do the names change? Commented Aug 22, 2017 at 17:36
  • The names change from dataset to dataset, so ideally I just want to access them with indexing. Commented Aug 22, 2017 at 17:37
  • Do you know the size beforehand, or do you get it from numberofCycles? Commented Aug 22, 2017 at 17:43
  • Only get it from numberOfCycles Commented Aug 22, 2017 at 17:45

1 Answer 1

1

Here it is a way of doing it:

% Get the names of the fields
fnames=fieldnames(mystruct);

% Get the fields that are both not a cell, and the correct size
thisones=~structfun(@iscell,mystruct)&structfun(@(x)(size(x,2)==mystruct.numberofCycles),mystruct);

% to make sure they are always 3 (else the struct is different of what you showed)
assert(sum(thisones)==3);

%Get the index of the fields
indices=find(thisones);

% make a matrix by appending the columns
result=zeros(3,mystruct.numberofCycles);
for ii=1:3
   result(ii,:)=mystruct.(fnames{indices(ii)});
end

Note that this will not work if you have 2 structures with size 1xN that are different types, but are not a cell. You would need to make the thisones condition more complex.

Sign up to request clarification or add additional context in comments.

11 Comments

Okay, so for my complete example I have 14 columns (instead of 3), and this is indicated by the numberOfChannels parameter. I tried replacing 3 with 14 in your code, but the last step fails with: 'Index exceeds matrix dimensions'. Should I also change the size(x,2) part?
@BradReed if it fails then it must be because you haven't replaced it in result=zeros... or because it did not find 14 fields
Breaking the code down, and running for just one of the indices, say ii=14, the fnames{indices(14)} works but it gives the error when trying to run mystruct(fnames{indices(14)}).
@BradReed what is size(indices)? 13? Then it has only found 13 fields. But I cant debug without the real case
No, its 14. Yes I know, sorry, I appreciate it's harder without the data.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.