Data Collection & Data Analyses

Previous page: How to use a spreadsheet
Next: Handling Submissions

Basics

So far we have seen how to display content and ask participants to interact with it. But all this is useless if we do not actually collect the participants’ input.

Basically, all you need to do is add .settings.log() to any element for which you want to save the response. For instance, if you have a TextInput element, you can call .settings.log() upon its creation to collect whatever text it contains at the end of the trials, like this:

newTextInput("feedback", "Type your comments")
    .settings.log()
    .settings.lines(0)
    .print()

For a scale, .settings.log() will collect the option currently selected at the end of the trials:

newScale("naturalness",   "Unnatural", "So-so", "Natural")
    .settings.log()
    .settings.button()
    .print()

What is collected when you call .settings.log() is pretty straightforward, but you can get more element-specific details on the reference documentation.

Application

Let’s simply add .settings.log() to the Scale and Selector elements of our current script. Nothing changes from the participants’ perspective, but the output results file will now contain lines reporting their input, as we will see below.

PennController.Sequence( randomize("picture") , randomize("rating") );
PennController.ResetPrefix(null);
PennController.AddHost("http://files.lab.florianschwarz.net/ibexfiles/PennController/SampleTrials/");

PennController.Template( PennController.defaultTable.filter("Type","rating") ,
    row => PennController( "rating" ,
        newText( "sentence" , row.Sentence )
        ,
        newScale("judgment",    "cold", "cool", "lukewarm", "warm", "hot")
            .settings.log()             // Record
            .settings.labelsPosition("top")
            .settings.before( getText("sentence") )
            .settings.size("auto")
            .print()
            .wait()
    )
);

PennController.Template( PennController.defaultTable.filter("Type","picture") ,
    row => PennController( "picture" ,
        defaultImage
            .settings.size(200, 200)
        ,
        newText("test sentence", row.Sentence)
            .print()
        ,
        newCanvas("patches", 500, 200)
            .settings.add(   0, 0, newImage("color1", row.Color1) )
            .settings.add( 300, 0, newImage("color2", row.Color2) )
            .print()
        ,
        newSelector("patch")
            .settings.log()             // Record
            .settings.add( getImage("color1") , getImage("color2") )
            .wait()
    )
);

In your Ibex project, click on refresh next to upload a file to this directory, itself next to the results folder. If you see two files named raw_results and results, click on delete next to their name: at this point, we want to start with a clean slate.

Now take the experiment until the results are saved and you arrive onto the final screen. Go back to your Ibex project and click refresh one more time: the results files now contain the output of the run you just took.

A look at the results file

Import

Click on the filename results under your Ibex project’s folder results to open it in a new tab in your browser. You should be seeing a bunch of lines starting with #. Save the file on your computer (File>Save, or Ctrl+S, or Apple+S). Make sure you know in which directory your are saving it, and that it ends with .csv.

The results file is a CSV file, so there are numerous ways of visualizing and manipulating its content. Here, we choose to use the online software Google Spreadsheet for its convenient Import and Filter functions, but feel free to use your own solution.

In a new Google spreadsheet, click on File and then Import.... In the frame that opens, click on the Upload tab. You can either click on Select a file from your computer to navigate to the folder in which you saved the results file and select the file, or you can directly drag-and-drop the results file from your system’s file navigator into the frame. Under Separator type in the Import file frame that opens, select the option Comma, and then click on the Import data button at the bottom.

Filtering

Now you have a bunch of rows starting with # and an uneven number of filled columns. This is where the filtering functions of Google Spreadsheet come in handy. Select all your spreadsheet by clicking on the upper-left corner, at the intersection of the row and column indexes. Then click on Data in the menu and select Create a filter. You will see reverse pyramidal line-shaped symbols appear below each column index. Click on the symbol for the A column, then on Filter by condition… and select Text does not contain, then enter # in the input box right below it and click OK. All the comment lines from the results file, starting with #, just disappeared.

The H column indicates the type of element which the row relates to. When you see PennController, this means that the row reports meta-trial data, typically at what times (in ms) the trial started and ended. In your case, you should also see some rows with Scale and TextInput in the H column. Those are the ones we are interested in, because they contain scores and text that were input by the participant (yourself, when you took the test-run(s)). Click the pyramidal symbol to filter the rows, click on Clear and then select Scale and Selector in the list and click on OK.

The column I reports the name of the element, as you specified it in your script. You can see a few rows with patch in that column, meaning that those rows report (the name of) which Image element was selected from the patch selector. That value is reported in the column K. You can also see some Scale rows for the elements named judgment. In K you see the labels of the buttons that were clicked.

Record trial and experiment information

All this is nice, but you may wonder which sentence the different rows correspond to, as well as which participant group the results correspond to. Ideally, we would like to have yet another couple of columns to determine which sentence and which group a data point (a row) corresponds to. PennController provides a simple way of adding extra columns to the results file for the trials, with the method .log, as illustrated below:

PennController.Sequence( randomize("picture") , randomize("rating") );
PennController.ResetPrefix(null);
PennController.AddHost("http://files.lab.florianschwarz.net/ibexfiles/PennController/SampleTrials/");

PennController.Template( PennController.defaultTable.filter("Type","rating") ,
    row => PennController( "rating" ,
        newText( "sentence" , row.Sentence )
        ,
        newScale("judgment",    "cold", "cool", "lukewarm", "warm", "hot")
            .settings.log()             // Record
            .settings.labels("top")
            .settings.before( getText("sentence") )
            .settings.size("auto")
            .print()
            .wait()
    ) // Call .log on the closing parenthesis of PennController
        .log( "Group" , row.Group ) // Value in the 'Group' column for the item's row
        .log( "Sentence" , row.Sentence ) // Value in the 'Sentence' column for the item's row
);

PennController.Template( PennController.defaultTable.filter("Type","picture") ,
    row => PennController( "picture" ,
        defaultImage
            .settings.size(200, 200)
        ,
        newText("test sentence", row.Sentence)
            .print()
        ,
        newCanvas("patches", 500, 200)
            .settings.add(   0, 0, newImage("color1", row.Color1) )
            .settings.add( 300, 0, newImage("color2", row.Color2) )
            .print()
        ,
        newSelector("patch")
            .settings.log()             // Record
            .settings.add( getImage("color1") , getImage("color2") )
            .wait()
    ) // Call .log on the closing parenthesis of PennController
        .log( "Group" , row.Group ) // Value in the 'Group' column for the item's row
        .log( "Sentence" , row.Sentence ) // Value in the 'Sentence' column for the item's row
);

Once again, in your Ibex project, click on delete next to raw_results and results and take the experiment until the results are saved and you arrive onto the final screen. Go back to your Ibex project and click refresh to obtain the results files that contain the new columns.

Repeat the Import and Filtering steps: as you can see, you now have two extra columns reporting Group and Sentence. If you used the two-table solution, this is only true for the Selector rows since there is no Group column in the rating table, but you can manually fill the columns for the TextInput rows if you want your results table square (though this rapidly becomes sub-optimal when you run many participants).

Save the results spreadsheet

Remember that what you are seeing now is a filtered version of the spreadsheet: though not visible with the filtering settings, the lines starting with # and all the other rows are still there (e.g. the rows corresponding to the start and the end of each trial). If you want to save a file containing only the filtered data points, simply copy the table (click on the top-left square at the intersection of the columns and the rows to select everything) into a new spreadsheet. Feel free to insert a new row at the top of the table to give insightful names to the different columns. Here is a suggestion, adding Ibex as a prefix to the columns generated by Ibex by default (except for Label which corresponds to the label of the item):

IbexReceptionTime IbexIP IbexController IbexItem IbexElement Label IbexGroup ElementType ElementName EventOrParameter Value EventTime Group Sentence Comments
1536892364 d268a9f58ece3e50a86a26608adbb4d4 PennController 7 0 picture NULL Selector patch Selection color1 1536892357384 More Which patch is oranger? NULL

Next: Handling Submissions