2 Assembling the trial list

2.1 Setup

The directory should be as follows:

+-- motion_data
|   +-- MDim1_s1_b1_0000.exp
|   +-- MDim1_s1_b1_0001.exp
|   +-- ...
+-- task_data
|   +-- MDim1 raw.txt

And the plyr and motionImport packages should be installed and loaded

library(plyr)
library(motionImport)

2.2 Guide

The file trial_data/MDim1 raw.txt contains the output from EPrime in the following format:

*start of subject*
s1
s1 R LV HRges CB 619 correct b1 t0
s1 R LH VLges CO 445 correct b1 t1
s1 R RV HLges CB 481 incorrect b1 t2
s1 R LV VRges CH 473 incorrect b1 t3
...

which lacks a column header and contains rows without trial data.

The file can be cleaned and imported using

# Column labels
labels <- c('Subject', 'Handedness', 'Cue', 'Switch.Cue', 
            'Change', 'RT', 'Accuracy', 'Block', 'Trial')

# Import trial data
trialData <- ImportTrialList('task_data/MDim1 raw.txt', labels)

# Show first few rows
head(trialData)
##   Subject Handedness Cue Switch.Cue Change  RT  Accuracy Block Trial
## 3      s1          R  LV      HRges     CB 619   correct    b1    t0
## 4      s1          R  LH      VLges     CO 445   correct    b1    t1
## 5      s1          R  RV      HLges     CB 481 incorrect    b1    t2
## 6      s1          R  LV      VRges     CH 473 incorrect    b1    t3
## 7      s1          R  RH      HLges     CH 642   correct    b1    t4
## 8      s1          R  LV      VLges     NC 306   correct    b1    t5

In some cases, there may be a mismatch between the number of trials recorded in data file and the number of motion monitor files. This is generally caused by the experimenter forgetting to restart the motion tracking system at the start of a new block, and missing a few trials. In this case, a subject will have fewer motion data files than trials, and the first few trials should be deleted from the data frame. In the opposite case, where recording is accidentally stopped early, the last few trials should be deleted. This can be done automatically using the PruneTrialList() function, which accepts the dataframe returned by ImportTrialList, and the path to the motion monitor files (here, in motion_data).

In some cases, especially with older expeeriments, certain .exp files did not contain trial data. Usually these had the word “hands” in the filename. In that case, the function accepts an optional third argument “exclude”, and will ignore any file with that argument in the name.

prunedData <- PruneTrialList(trialData, path = 'motion_data')

Now we just do some recoding of the trial variables, and create a few new variables, to make them easier to work with later.

df <- prunedData

# Remove the letter prefix from the subjects, block, and trial  columns
df$Subject <- as.numeric(substring(df$Subject, first = 2))
df$Block   <- as.numeric(substring(df$Block, first = 2))
df$Trial   <- as.numeric(substring(df$Trial, first = 2))

# I like capitalization...
df$Accuracy <- revalue(df$Accuracy, c('correct' = 'Correct',
                                      'incorrect' = 'Incorrect'))

# Add a separate column to indicate green dot vs. change
df$Signal <- revalue(df$Change, c('CO' = 'Stop', 'CH' = 'Stop',
                                  'CB' = 'Stop', 'NC' = 'Stop', 
                                  'GD' = 'Go'))

# Rename levels of change variable
df$Change <- revalue(df$Change, c('CO' = 'Orientation', 'CH' = 'Hand',
                                  'CB' = 'Both', 'NC' = 'None', 
                                  'GD' = 'None'))

# Create variables for initially cued hand and orientation
df$Cue.Hand <- revalue(df$Cue, c('RV' = 'Right', 'RH' = 'Right',
                                 'LV' = 'Left',  'LH' = 'Left'))
df$Cue.Orientation <- revalue(df$Cue, c('RV' = 'Vertical', 'RH' = 'Horizontal',
                                        'LV' = 'Vertical', 'LH' = 'Horizontal'))


# Create variables for response hand and orientation
df$Response.Hand <- sapply(1:nrow(df), function(i) {
    
    # If trial was a green light, then hand is the same as cue
    if (df$Switch.Cue[i] == 'GRN') {
        return(as.character(df$Cue.Hand[i]))
    } else if (df$Switch.Cue[i] %in% c('HLges', 'VLges')){
        return('Left')
    } else {
        return('Right')
    }
})

df$Response.Orientation <- sapply(1:nrow(df), function(i) {
    
    # If trial was a green light, then orientation is the same as cue
    if (df$Switch.Cue[i] == 'GRN') {
        return(as.character(df$Cue.Orientation[i]))
    } else if (df$Switch.Cue[i] %in% c('HLges', 'HRges')){
        return('Horizontal')
    } else {
        return('Vertical')
    }
})

# Remove unneeded columns
df[,c('Handedness', 'Cue', 'Switch.Cue')] <- NULL

# Reorder columns...
df <- df[,c(1,5,6,9,10,11,12,8,2,3,4,7)]

# View dataframe
head(df)
##   Subject Block Trial Cue.Hand Cue.Orientation Response.Hand
## 3       1     1     0     Left        Vertical         Right
## 4       1     1     1     Left      Horizontal          Left
## 5       1     1     2    Right        Vertical          Left
## 6       1     1     3     Left        Vertical         Right
## 7       1     1     4    Right      Horizontal          Left
## 8       1     1     5     Left        Vertical          Left
##   Response.Orientation Signal      Change  RT  Accuracy         FileName
## 3           Horizontal   Stop        Both 619   Correct MDim1_s1_b1_0000
## 4             Vertical   Stop Orientation 445   Correct MDim1_s1_b1_0001
## 5           Horizontal   Stop        Both 481 Incorrect MDim1_s1_b1_0002
## 6             Vertical   Stop        Hand 473 Incorrect MDim1_s1_b1_0003
## 7           Horizontal   Stop        Hand 642   Correct MDim1_s1_b1_0004
## 8             Vertical   Stop        None 306   Correct MDim1_s1_b1_0005

Now we save the trial in the task_data directory:

write.table(df, file = 'task_data/trial_data.csv',
            sep = ',', row.names = F)