psychopy.org | Reference | Downloads | Github

Trying to output only one row of data per trial rather than two

#1

OS: macOS High Sierra
PsychoPy version: 1.90.2
Standard Standalone

Hi,
I made an experiment on Builder where participants are presented with a sentence and are asked to produce a word that appears after the sentence. I took the “word_naming” demo in order to output the vocal RT and recordings, which seem to be working fine.
Occasionally on some of the trials, participants are presented with a question they need to answer with a button press following the word production. This, I managed to do with a loop. and the questions are properly presented and responses correctly outputted.

However, when I look at the excel output, I get two lines of data per trial, the first including mainly the vocal RT and voice recording filename, and the second line including the question response and accuracy data.
For the purposes of analyses, I would like an output format where there is only one line per trial rather than two. I’ve unchecked the “Is trials” box off of the loop that determines the occasional question to be displayed, but this still results in two lines of data.

Any help would be appreciated.
Many thanks in advance.

#2

We probably need to see a screenshot of your flow panel, a section of your data file output, and know how you are controlling the loops.

#3

Hi Michael,

Thank you so much for your time and your help. I’ve attached the necessary screenshots.

The flow.panel file shows the general flow of the experiment, with:
1.Trial Sentence routine which presents a fixation, sentence, and response press.
2. ExpTrial_TargetWord routine including a target word the participants have to produce followed by the Voice recording code that I took off of the “word_naming” demo.
3. BlockSelect routine that includes a code component which determines whether there is a question, and if there is, to present it. These are specified under the “Begin Experiment” as “nRepsCompQ=0” and "Begin Routine” tab as an if, elif statement.
4. CompQ routine including the question text and a response press
5. the Pause routine at the beginning presents a break in the middle of the experiment. It includes code to determine the count under “Each Frame” tab and a “take a break” text and response key
6. The specification of loops can be checked in the screenshot files.

As you can see in the excel output shot, each item is split into two rows, with the first including the voice recorded information and the second line with the question. The second line is blank if there is no corresponding question.

#4

OK, I’m going to guess that this is due to the second (inner) loop, even though you’ve set it to not be “is trials”. This arrangement of putting a loop around a routine is an old kludge solution that we can now address more directly. So:

  1. Delete that loop.
  2. Insert a code component on that routine. In the “begin routine” tab, put something like:
if ask_question != 'Y':
    continueRoutine = False

i.e. this means that routine will only run if the value of that variable is ‘Y’. Use whatever variable name makes sense, and whatever value works. i.e. I guess you already have this in your conditions file coded as 1 or 0, or you somehow determine it in the code component you already have. That code component (and the whole BlockSelect routine) can become redundant: you could handle it all in the code component of the CompQ routine.

You now only have one loop, so you should just get one row per trial in your data file.

#5

Hi,
Thanks so much for advising me on this.
As suggested, I got rid of the BlockSelect routine and the ExpCompQLoop.
I inserted a code at the beginning of the CompQ routine with the following code in the “begin routine” tab:
if show_compQ != ‘Yes’:
continueRoutine = False

but this resulted in two rows of output (screenshot attached).

I also did other variations like:
if show_compQ==‘Yes’:
continueRoutine = True
elif show_compQ==“No”:
continueRoutine = False

But again, this also results in two rows.

#6

I think we’re going to need to see more (the screen shot of the data file seems to be referring in one of the columns to a loop we can’t see in the flow panel screenshot). Can you post the actual data file, the conditions files, and the .psyexp file?

#7

Sorry for the confusion. There was a practice loop prior to experiment loop.
This is the version where I removed the inner loop as you suggested.

1_SOA_2018_Aug_23_1223.csv (4.2 KB)
SOA.psyexp (36.9 KB)
experiment_stimuli.xlsx (9.3 KB)
practice_stimuli.xlsx (9.5 KB)

#8

Looking at the generated Python script for your experiment, I think things may have gotten a little corrupted along the way. There is a call to thisExp.nextEntry() before your CompQ runs, which means that the ExperimentHandler is going to the next row of data before that final routine within the loop has run.

Could you make a copy of your Builder file, remove the CompQ routine from both of its appearances within the flow panel, and save, close, and re-open that file? Hopefully you can then re-enter the routine back where it should be, and get the correct sequence of events happening again.

#9

I went back and removed the CompQ routine, saved, reopen etc the file as you suggested. This didn’t have a direct effect on the output but I was looking at my experiment file and I noticed that in the Target word routine preceding the CompQ routine, I had copied the code to record voice input from the word_naming demo. In this code, there actually was the call to thisExp.nextEntry() as you suggested in the “End Routine” tab. Removing this call did the trick and the output gives the expected one line per trial format.

Thank you Michael so much for the time you invested in helping me. Hopefully I can learn more about the coding portion of Psychopy more! Thank you!

#10

Hello,

I have a similar problem with my experiment:


maskedPriming2_lastrun.py (71.6 KB)

While loop nesting could be avoided in the case above, there seems to be no other way in my case. Loop nesting is necessary to enforce pseudo-randomization of the trials presented after the break (more info in this topic). The matter is that the output file contains two row per each of the trials of the outer loop loopWarm, the second of which corresponds to the RTs relative to keyboard component of the last routine of the inner loop loopWarm2, as shown here:

_maskedPriming_2019_May_14_1357.csv (2.6 KB)

I can’t seem to understand why the trials presented in the inner loop loopWarm2 are not copied in the output file. I have also tried to use loopWarm2.addData() commands at the end of each of the routines of the loop, but it did not do anything at all.

Please let me know if any of you has any idea of how to fix this. What I would like to achieve is to get an output file with one row for each trial (regardless of which loop they are presented in). Thank you in advance!

#11
  • Is the loop set to be “Is trials”? (It should be.) This option allows for loops that repeat actions but shouldn’t be seen as controlling trials (e.g. for repetition within a trial), and hence don’t generate data.
  • Hopefully the above fixes the issue, but if not, use thisExp.addData() instead of loopWarm2.addData(), to add data to the experiment handler, rather than an individual loop.
#12

Thanks for replying @Michael!

I added thisExp.addData() to the end section of each of the two routines (i.e., primeWarm2 and targetWarm2) within the inner loop loopWarm2:

#End of routine `primeWarm2`
thisExp.addData('prime', text_primeWarm2.text)
...
#End of routine `targetWarm2`
thisExp.addData('target', text_targetWarm2.text)
        thisExp.addData('key_targetWarm2.keys',key_targetWarm2.keys)
        thisExp.addData('key_targetWarm2.corr', key_targetWarm2.corr)
        if key_targetWarm2.keys != None:  # we had a response
            thisExp.addData('key_targetWarm2.rt', key_targetWarm2.rt)

but this duplicated the columns prime and target in output file as shown in the attached csv: _maskedPriming_2019_May_15_0719.csv (2.4 KB)

Let me give you some background on the script. Knowing what the two loops do might be necessary to understand how to fix the problem. In this experiment, a single condition file lists one experimental condition and one filler condition. Each condition has the same number of prime-target trial couplets. After a given number of trials, a break routine breakWarm appears. I need to make sure that 1 filler trial couplet appears after each break. Therefore, the routines in the inner loop loopWarm2 (i.e., fmaskWarm2-primeWarm2-targetWarm2) appear only if when the routine breakWarm appears. The two loops are both isTrials and they are linked to different conditions file. The outer loop loopWarm is linked to its conditions file through trialHandler. The inner loop loopWam2 is linked to its conditions file as follows:

#Begin experiment
breakFillers = data.importConditions("warm_up2.csv")
shuffle(breakFillers)

This was the only way to take control over the actual stimuli in textComponents of the routines within loopWarm2 (thanks to @dvbridges for the suggestion!).
I am sorry if this is too long, but I figured it might be useful to understand how the script works.

Thank you in advance!