Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
get struct field including empty values

Subject: get struct field including empty values

From: John

Date: 10 May, 2013 15:44:12

Message: 1 of 13

I have conducted an experiment and saved all trials as a structure with relevant parameters as fields.

If I only want to use the correct trials, I am using:
indices = find([allData.correct]==1);

However, It is only now (that I am using this strucure with over 30'000 trials that I discover that this works incorrectly when some of the field values are empty or not a number.

Then length(allData.correct) < length(allData)

How do I obtain an array of all the trials values of a specific field, which is representive with respect to the index number?

Thanks!!

Subject: get struct field including empty values

From: dpb

Date: 10 May, 2013 17:11:56

Message: 2 of 13

On 5/10/2013 10:44 AM, John wrote:
> I have conducted an experiment and saved all trials as a structure with
> relevant parameters as fields.
>
> If I only want to use the correct trials, I am using:
> indices = find([allData.correct]==1);
>
> However, It is only now (that I am using this strucure with over 30'000
> trials that I discover that this works incorrectly when some of the
> field values are empty or not a number.
> Then length(allData.correct) < length(allData)
>
> How do I obtain an array of all the trials values of a specific field,
> which is representive with respect to the index number?

The index returned by find() will still be representative of the actual
position; it simply is condition by the logical expression you have used
in the search to (correctly) not return values that don't match the
condition.

If you want all members of a field, then don't put a conditional test on
it; simply

x=allData.xVarFieldName;

And, of course, you don't need the new variable necessarily, just
reference what you want.

If that doesn't suit, post more details of why there was any question on
this to begin with as I'm somewhat puzzled by what seems to be obvious...

--

Subject: get struct field including empty values

From: Steven_Lord

Date: 10 May, 2013 20:25:19

Message: 3 of 13



"John " <john.wielenbroek@tivaro.nl> wrote in message
news:kmj4kc$emn$1@newscl01ah.mathworks.com...
> I have conducted an experiment and saved all trials as a structure with
> relevant parameters as fields.
>
> If I only want to use the correct trials, I am using:
> indices = find([allData.correct]==1);
>
> However, It is only now (that I am using this strucure with over 30'000
> trials that I discover that this works incorrectly when some of the field
> values are empty or not a number.
> Then length(allData.correct) < length(allData)

It works correctly. It doesn't work the way you expected. Those are two
different things.

x = [1 [] 3] % The result is a 2-element vector [1 3].

Normally concatenation like that requires all the quantities being
concatenated to have the same number of rows. For backwards compatibility,
if I remember correctly, concatenating with [] is exempt from that
requirement and the [] is squeezed out of the resulting vector. I requested
that the development staff work on getting that documented in an
easy-to-find location.

> How do I obtain an array of all the trials values of a specific field,
> which is representive with respect to the index number?

What does it mean for allData(17).correct to be empty or NaN? [I chose 17
arbitrarily.] Shouldn't allData(n).correct be required to ALWAYS contain
either true or false? I would likely make my code default to allData.correct
being false, then only if I validate that the data is correct should the
field be changed and it should only be changed to true.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: get struct field including empty values

From: dpb

Date: 10 May, 2013 20:47:58

Message: 4 of 13

On 5/10/2013 12:11 PM, dpb wrote:
> On 5/10/2013 10:44 AM, John wrote:
...

>> If I only want to use the correct trials, I am using:
>> indices = find([allData.correct]==1);
>>
>> However, It is only now (that I am using this strucure with over 30'000
>> trials that I discover that this works incorrectly when some of the
>> field values are empty or not a number.
>> Then length(allData.correct) < length(allData)
>>
>> How do I obtain an array of all the trials values of a specific field,
>> which is representive with respect to the index number?
>
> The index returned by find() will still be representative of the actual
> position; it simply is condition by the logical expression you have used
> in the search to (correctly) not return values that don't match the
> condition.
>
> If you want all members of a field, then don't put a conditional test on
> it; simply
>
> x=allData.xVarFieldName;
>
> And, of course, you don't need the new variable necessarily, just
> reference what you want.
>
> If that doesn't suit, post more details of why there was any question on
> this to begin with as I'm somewhat puzzled by what seems to be obvious...

What came to me later and while reading Steven's response which covers
another aspect very well is that maybe what you're looking for is
"logical addressing" so that the length is still full length if needed
for consonance w/ another operation but is still only operating on the
desired elements.

If that's it, instead of find() use

allData(allData.correct==1).FieldName

--

Subject: get struct field including empty values

From: dpb

Date: 10 May, 2013 20:58:37

Message: 5 of 13

On 5/10/2013 3:47 PM, dpb wrote:
...

> allData(allData.correct==1).FieldName

Or, of course, if you make the field 'correct' a logical instead of
numeric then you can dispense w/ the '==1' part and simply write

allData(allData.correct).FieldName

--

Subject: get struct field including empty values

From: John

Date: 11 May, 2013 12:38:07

Message: 6 of 13

dpb <none@non.net> wrote in message <kmjn0s$hkl$1@speranza.aioe.org>...
> On 5/10/2013 3:47 PM, dpb wrote:
> ...
>
> > allData(allData.correct==1).FieldName
>
> Or, of course, if you make the field 'correct' a logical instead of
> numeric then you can dispense w/ the '==1' part and simply write
>
> allData(allData.correct).FieldName
>
> --
>

Hey guys thanks for your responses.

allData(allData.correct==1) does not work because allData.correct returns every value as a unique anser, the solution to this is
allData([allData.correct==1]) but this raises the same problem as stated in my first post.

The reason I allow empty values is in this case to differentiate between correct responses, incorrect responses, and no responses.

In fact, I wrote a function which returns indices of trials with specific paramaters the function works like:
indices = findTrial(allData,'correct',1,'reactionTime','>300','block',{'A','B','C'})
returns the indices of the correct trials with a reactionTime > 300 conducted in block A, B or C.

Sinces I want this function to be applicable as best as possible, I don't care for empty or missing values untill a condition is set. So it is ok if there are missed trials (maybe we do want to look at other measurements and we are indifferent to the response) unless, we only want correct, or incorrect trials, in that case, we will leave the empty trials out.

A solution would be to check for empty values of all the fields specified in the function findTrial, since once such a field is given, a condition is set, and we therefore do not allow empty fields. So my problem would also be solved if there is a way of obtaining al empty values of a field.

Subject: get struct field including empty values

From: Bruno Luong

Date: 11 May, 2013 14:07:08

Message: 7 of 13

"John" wrote in message <kmle3f$p5r$1@newscl01ah.mathworks.com>...

>
> A solution would be to check for empty values of all the fields specified in the function findTrial, since once such a field is given, a condition is set, and we therefore do not allow empty fields. So my problem would also be solved if there is a way of obtaining al empty values of a field.

>> alldata = struct('correct',{1 2 3 [] 5})

alldata =

1x5 struct array with fields:

    correct

>> c = cellfun('isempty',{alldata.correct})

ans =

     0 0 0 1 0

>> find(c) % if needed

ans =

     4

% Bruno

Subject: get struct field including empty values

From: Bruno Luong

Date: 11 May, 2013 15:11:09

Message: 8 of 13

> >> c = cellfun('isempty',{alldata.correct})
>

Equivalent statement is:
 
arrayfun(@(s) isempty(s.correct),alldata)

Not sure which one is faster. Probably the first one.

Bruno

Subject: get struct field including empty values

From: John

Date: 13 May, 2013 08:57:07

Message: 9 of 13

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <kmln2d$gmj$1@newscl01ah.mathworks.com>...
> > >> c = cellfun('isempty',{alldata.correct})
> >
>
> Equivalent statement is:
>
> arrayfun(@(s) isempty(s.correct),alldata)
>
> Not sure which one is faster. Probably the first one.
>
> Bruno

Thanks for your reply!

cellfun is in fact way faster using an 1 x 30.000 struct. Is there a fast way to inverse the result?
In other words, wat is the cellfun equivalent of arrayfun(@(s) ~isempty(s.correct),alldata)

Subject: get struct field including empty values

From: Bruno Luong

Date: 13 May, 2013 09:02:08

Message: 10 of 13

"John" wrote in message <kmq9t3$mj$1@newscl01ah.mathworks.com>...

>
> cellfun is in fact way faster using an 1 x 30.000 struct. Is there a fast way to inverse the result?
> In other words, wat is the cellfun equivalent of arrayfun(@(s) ~isempty(s.correct),alldata)

c = ~cellfun('isempty',{alldata.correct})

Bruno

Subject: get struct field including empty values

From: John

Date: 13 May, 2013 09:07:08

Message: 11 of 13

"John" wrote in message <kmq9t3$mj$1@newscl01ah.mathworks.com>...
> "Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <kmln2d$gmj$1@newscl01ah.mathworks.com>...
> > > >> c = cellfun('isempty',{alldata.correct})
> > >
> >
> > Equivalent statement is:
> >
> > arrayfun(@(s) isempty(s.correct),alldata)
> >
> > Not sure which one is faster. Probably the first one.
> >
> > Bruno
>
> Thanks for your reply!
>
> cellfun is in fact way faster using an 1 x 30.000 struct. Is there a fast way to inverse the result?
> In other words, wat is the cellfun equivalent of arrayfun(@(s) ~isempty(s.correct),alldata)

Ohw I am sorry, this would be
~cellfun('isempty',{alldata.correct});
Forgot how elegant matlab is!

Subject: get struct field including empty values

From: John

Date: 13 May, 2013 09:07:08

Message: 12 of 13

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <kmqa6g$1b6$1@newscl01ah.mathworks.com>...
> "John" wrote in message <kmq9t3$mj$1@newscl01ah.mathworks.com>...
>
> >
> > cellfun is in fact way faster using an 1 x 30.000 struct. Is there a fast way to inverse the result?
> > In other words, wat is the cellfun equivalent of arrayfun(@(s) ~isempty(s.correct),alldata)
>
> c = ~cellfun('isempty',{alldata.correct})
>
> Bruno

Yes thank you,
I forgot how elegant matlab is!

Subject: get struct field including empty values

From: Steven_Lord

Date: 13 May, 2013 13:59:06

Message: 13 of 13



"John " <john.wielenbroek@tivaro.nl> wrote in message
news:kmle3f$p5r$1@newscl01ah.mathworks.com...
> dpb <none@non.net> wrote in message <kmjn0s$hkl$1@speranza.aioe.org>...
>> On 5/10/2013 3:47 PM, dpb wrote:
>> ...
>>
>> > allData(allData.correct==1).FieldName
>>
>> Or, of course, if you make the field 'correct' a logical instead of
>> numeric then you can dispense w/ the '==1' part and simply write
>>
>> allData(allData.correct).FieldName
>>
>> --
>>
>
> Hey guys thanks for your responses.
>
> allData(allData.correct==1) does not work because allData.correct returns
> every value as a unique anser, the solution to this is
> allData([allData.correct==1]) but this raises the same problem as stated
> in my first post.
>
> The reason I allow empty values is in this case to differentiate between
> correct responses, incorrect responses, and no responses.

So you're looking for a ternary state and simulating this by using the
binary logical class plus empty. I'd probably switch this around and use 1
for correct answer, -1 for incorrect answer, and 0 for no answer. If you're
worried about an increase in memory consumption, use int8 instead of double.

CORRECT = int8(1);
INCORRECT = int8(-1);
NOANSWER = int8(0);
allData(1).correct = NOANSWER;
allData(1).correct == INCORRECT % false
allData(1).correct == NOANSWER % true

With this coding system, your concatenation-based syntax:

allData([allData.correct]==CORRECT)

just works.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us