Extracting reading measures from Tobii Studio eye-tracking data in R

© Dr Gareth McCray

garethmccray@gmail.com

Using R for the first time can be a daunting experience. I have written this short guide to talk you through step by step how to use a selection of functions I have written to extract various eye tracking measures from data collected with Tobii Studio. I haven’t gone into any detail with how to install R and get it up and running, you will be able to find lots of info on how to do that through Google. Ok, so you want to analyse some eye-tracking data, follow these steps, if you skip any, it won’t work so read through carefully.

1, Make sure that you have the I-VT filter selected. 2, Export your data from Tobii Studio as individual files:

3, Open R and change the directory to the directory containing the exported files (google it). Open a new script from “File>New Script”.

4, The output from Tobii studio is potentially very large and we do not actually need all the data so before we can do any analysis we have to turn the data into a more convenient format. To do this we use the function “Tobii.trim”.

## output <- TobiiTrim(recs = recordings, fileroot = "Pilot 2_Unnamed test_Rec ", n.aoi=24)

Now you are ready to run the otehr analysis functions. Remember “ang.tolerance” is the angle in degrees from the x-axis that when a regression of forwards saccade falls outside this angle, from the orifin, it will not be counted/considered as a regression or forwards saccade. “length.tolerance” is a value, in pixles, beyond which regressions/forwards saccades will not be counted as regression/forwards saccades and rather be classified as return sweeps or searches. I’ll let you work out the rest :)

Functions for analysis

This first function, “Tobii.trim” turns the data into a more manageable format

TobiiTrim<-function(recs, fileroot, n.aoi){

# this sets up the first line (which will be deleted) of a matrix to store all the data.  This is done so we can rbind().

        first.line<-matrix(nrow=1, ncol=(7+(n.aoi)+2+1+1), NA)

#This part checks that the recodrings that you say are there are actually there taking time now but saving pain later on.  Fix this to just real 1 line.

    #for (j in 1:length(recs)){dat<-read.table(paste(fileroot, recs[j] , ".tsv", sep=""),sep="\t", header=TRUE) ; print(paste("Checking file", recs[j]))}

# this is a 'loop' that cycles through each for the recs in turn
        for (i in 1:length(recs)){

# progress bar

                print(paste("Analysing Recording", recs[i]))

# this loads the data
        dat<-read.table(paste(fileroot, recs[i] , ".tsv", sep=""),sep="\t", header=TRUE)
        dat=dat[,-length(dat[1,])]


# this reduces the size of the data because it is too big and that slows things down later on
        dat <- unique(dat)
        dat<-dat[dat$GazeEventType == "Fixation",]
       
# fill the NAs with 0s or the next bit won't work
        for (j in 8:(7+n.aoi)){dat[is.na(dat[,j]),j]<-0}

### This is the main bit

# this bit extracts the saccades/regressions
# here we create the additional variables to hold the saccades/regressions

# This bit creates an AOI tag for later analysis

rm(list=grep(x= ls(), pattern="AOI.", value=TRUE))

            for(j in 8:(7+n.aoi)){assign(paste(names(dat)[j]), matrix(ncol=1, nrow=length(dat[,1]), NA))}

                aoi.tag <- as.data.frame(matrix(ncol=1, nrow=length(dat[,1])))
                names(aoi.tag)<-"aoi.tag"
                aoi.names <- grep(x = ls(), pattern="AOI.", value=TRUE)
                rm(list=grep(x= ls(), pattern="AOI.", value=TRUE))   
               

                    for (j in 1:length(dat[,1])){
                        if (any(dat[j,8:(7+n.aoi)] == 1))     {aoi.tag[j,] <- names(dat[(which(dat[j,8:(7+n.aoi)] == 1))+7])}
                                        }
                   
                    for (j in 1:length(dat[,1])){
                        if(is.na(aoi.tag[j,])==FALSE)    {aoi.tag[j,] <- substr(aoi.tag[j,], start = 5, stop = (nchar(aoi.tag[j,])-4))}
                                    }

                aoi.tag[is.na(aoi.tag)]<-"NA"

## This extracts all x axis movement       

    comb.x.movement<-matrix(ncol=1, nrow=length(dat[,1]), NA)

    for (k in 2:(length(dat[,1])))    {comb.x.movement[k]<-(dat[k,6]-dat[k-1,6])}                               
  
## This loop extracts the Y-axis movement.  We need this for checking whether a saccade is a reading saccade or not.
   
    comb.y.movement<-matrix(ncol=1, nrow=length(dat[,1]), NA)

    for (k in 2:(length(dat[,1])))    {comb.y.movement[k]<-dat[k,7]-dat[k-1,7]}       

## pop all the data togheter for later                        }

    dat<-cbind(dat, comb.x.movement ,comb.y.movement, aoi.tag)
   
## ok we have the measures
## add a name tag to the person
tag<-matrix(ncol=1, nrow=length(dat[,1]), paste("Rec",recs[i]))
dat2<-cbind(tag, dat)
## put all the data together in 1 dataframe

first.line<-as.data.frame(first.line)
names(first.line)<-names(dat2)
if (i==1) {dat3<-rbind(dat2, first.line)}
if (i>1) {dat3<-rbind(dat3, dat2, first.line)}
                                            }

#########  This is where the main loop ends, below is tidying up

dat<-dat3
dat<-dat[is.na(dat$tag)==F,]

return(dat)
}

This function extracts median length of regressions

MedReg <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45 , length.tolerance = 100000){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

            med.reg.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(med.reg.out)<-"median length of regressions"
            row.names(med.reg.out)<-(recs)

   

   
        for (i in 1:length(med.reg.out[,1])){
                med.reg.out[i,1]<-median(trimmed.data$comb.x.movement[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     (trimmed.data$comb.x.movement < 0) &
                                     (((abs(trimmed.data$comb.y.movement)/abs(trimmed.data$comb.x.movement))) < deg.err) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)}) &
                                    sapply(trimmed.data$tag, function(check){any(check==recs)}) &
                                    (abs(trimmed.data$comb.x.movement)<length.tolerance)   
                                    ], na.rm=TRUE)
                                   }
return(med.reg.out)
}

This function extracts the median length of forwards saccades

MedForSac <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45 , length.tolerance = 100000){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

            med.for.sac.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(med.for.sac.out)<-"median length of forwards saccades"
            row.names(med.for.sac.out)<-(recs)

   
       
        for (i in 1:length(med.for.sac.out[,1])){
                med.for.sac.out[i,1]<-median(trimmed.data$comb.x.movement[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     (trimmed.data$comb.x.movement > 0) &
                                     (((abs(trimmed.data$comb.y.movement)/abs(trimmed.data$comb.x.movement))) < deg.err) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)}) &
                                    sapply(trimmed.data$tag, function(check){any(check==recs)}) &
                                    (trimmed.data$comb.x.movement<length.tolerance)   
                                    ], na.rm=TRUE)
                                   }
return(med.for.sac.out)
}

This function extracts the proportion of regresions

PropReg <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45 , reg.length.tolerance = 100000, for.length.tolerance=10000){



prop.reg.out <- as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(prop.reg.out) <- "Proportion of Regressions"
            row.names(prop.reg.out) <- (recs)


prop.reg.out <- NReg(trimmed.data , recs = recs , aois = aois , ang.tolerance = ang.tolerance, length.tolerance = reg.length.tolerance)/
            (NForSac(trimmed.data , recs = recs , aois = aois , ang.tolerance = ang.tolerance, length.tolerance = for.length.tolerance)+
            (NReg(trimmed.data , recs = recs , aois = aois , ang.tolerance = ang.tolerance, length.tolerance = reg.length.tolerance)))

return(prop.reg.out)
}

This function extracts the total number of forward saccades made in pixals

NForSac <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45 , length.tolerance = 100000){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

            n.for.sac.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(n.for.sac.out)<-"number of forwards saccades"
            row.names(n.for.sac.out)<-(recs)

   
       
        for (i in 1:length(n.for.sac.out[,1])){
                n.for.sac.out[i,1]<-table((trimmed.data$comb.x.movement[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     (trimmed.data$comb.x.movement > 0) &
                                     (((abs(trimmed.data$comb.y.movement)/abs(trimmed.data$comb.x.movement))) < deg.err) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)}) &
                                    sapply(trimmed.data$tag, function(check){any(check==recs)}) &
                                    (trimmed.data$comb.x.movement<length.tolerance)   
                                    ])==FALSE)
                                   }
return(n.for.sac.out)
}

This function extracts the median fixation duration

MedFixDur <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"])){

        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            med.fix.dur.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(med.fix.dur.out)<-"median of fixations"
            row.names(med.fix.dur.out)<-(recs)

   

   
        for (i in 1:length(med.fix.dur.out[,1])){
                med.fix.dur.out[i,1]<-median(trimmed.data$GazeEventDuration[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)})
                                    ], na.rm=TRUE)
                                   }
return(med.fix.dur.out)
}

This function extracts the sum fixation duration

SumFixDur <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"])){

        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            sum.fix.dur.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(sum.fix.dur.out)<-"Sum of fixations"
            row.names(sum.fix.dur.out)<-(recs)

   

   
        for (i in 1:length(sum.fix.dur.out[,1])){
                sum.fix.dur.out[i,1]<-sum(trimmed.data$GazeEventDuration[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)})
                                    ], na.rm=TRUE)
                                   }
return(sum.fix.dur.out)
}

This function extracts the total number of fixations

NFix <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"])){

        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            n.fix.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(n.fix.out)<-"Number of fixations"
            row.names(n.fix.out)<-(recs)

       
        for (i in 1:length(n.fix.out[,1])){
                n.fix.out[i,1]<-sum(table(trimmed.data$GazeEventDuration[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)})
                                    ]))
                                   }
return(n.fix.out)
}

This function extracts the total number of regressions in pixals

NReg <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45 , length.tolerance = 100000){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

            n.reg.out<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(n.reg.out)<-"number of regressions"
            row.names(n.reg.out)<-(recs)

   

   
        for (i in 1:length(n.reg.out[,1])){
                n.reg.out[i,1]<-table((trimmed.data$comb.x.movement[
                                      (trimmed.data$tag == paste(recs[i])) &
                                     (trimmed.data$comb.x.movement < 0) &
                                     (((abs(trimmed.data$comb.y.movement)/abs(trimmed.data$comb.x.movement))) < deg.err) &
                                     sapply(trimmed.data$aoi.tag, function(check){any(check==aois)}) &
                                    sapply(trimmed.data$tag, function(check){any(check==recs)}) &
                                    (abs(trimmed.data$comb.x.movement)<length.tolerance)   
                                    ])==FALSE)
                                   }
return(n.reg.out)
}

This function extracts the mean length of saccadic runs (in saccades) greater than a minimum

SacRun <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45,  length.tolerance = 100000 , min.sac.run = 1){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

sac.run<-matrix(nrow=length(trimmed.data[,1]),ncol=1,NA)

           
            for (i in 1:length(trimmed.data[,1])){
                            if((is.na(trimmed.data$comb.x.movement[i]) == FALSE))
                                { if((trimmed.data$comb.x.movement[i] > 0) &
                                ((abs(trimmed.data$comb.y.movement[i])/abs(trimmed.data$comb.x.movement[i])) < deg.err) &
                                    any(trimmed.data$aoi.tag[i] == aois) &
                                    any(trimmed.data$tag[i] == recs) &
                                    (trimmed.data$comb.x.movement[i] < length.tolerance))
                                {sac.run[i]<-1}}}

            for (i in 1:(length(trimmed.data[,1])-1)){
                            if((is.na(sac.run[i])==FALSE) & (is.na(sac.run[i+1])==FALSE))
                                {sac.run[i+1]<-sac.run[i]+1
                                 sac.run[i]<-NA}
                                    }

            n.sac.run<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(n.sac.run)<-"median length of regressions"
            row.names(n.sac.run)<-(recs)

                for (i in 1:length(recs)){
                n.sac.run[i,]<-mean(sac.run[(trimmed.data$tag==paste("Rec", recordings[i])) & sac.run > min.sac.run], na.rm=T)
                            }

return(n.sac.run)

}#end function

This function extracts the length of saccadic run in pixles for runs greater than a specified number of pixels

LenSacRun <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45,  length.tolerance = 100000 , min.sac.run = 20){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

sac.run<-matrix(nrow=length(trimmed.data[,1]),ncol=1,NA)

           
            for (i in 1:length(trimmed.data[,1])){
                            if((is.na(trimmed.data$comb.x.movement[i]) == FALSE))
                                { if((trimmed.data$comb.x.movement[i] > 0) &
                                ((abs(trimmed.data$comb.y.movement[i])/abs(trimmed.data$comb.x.movement[i])) < deg.err) &
                                    any(trimmed.data$aoi.tag[i] == aois) &
                                    any(trimmed.data$tag[i] == recs) &
                                    (trimmed.data$comb.x.movement[i] < length.tolerance))
                                {sac.run[i]<-trimmed.data$comb.x.movement[i]}}}

            for (i in 1:(length(trimmed.data[,1])-1)){
                            if((is.na(sac.run[i])==FALSE) & (is.na(sac.run[i+1])==FALSE))
                                {sac.run[i+1]<-sac.run[i]+sac.run[i+1]
                                 sac.run[i]<-NA}
                                    }

            len.sac.run<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(len.sac.run)<-"length of forward saccadic run (px)"
            row.names(len.sac.run)<-(recs)

                for (i in 1:length(recs)){
                len.sac.run[i,]<-mean(sac.run[(trimmed.data$tag==paste("Rec", recordings[i])) & sac.run > min.sac.run], na.rm=T)
                            }

return(len.sac.run)

}#end function

This function extracts the mean length of regressive runs (in regressions) greater than a minimum

RegRun <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45,  length.tolerance = 100000 , min.reg.run = 1){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

reg.run<-matrix(nrow=length(trimmed.data[,1]),ncol=1,NA)

           
            for (i in 1:length(trimmed.data[,1])){
                            if((is.na(trimmed.data$comb.x.movement[i]) == FALSE))
                                { if((trimmed.data$comb.x.movement[i] < 0) &
                                ((abs(trimmed.data$comb.y.movement[i])/abs(trimmed.data$comb.x.movement[i])) < deg.err) &
                                    any(trimmed.data$aoi.tag[i] == aois) &
                                    any(trimmed.data$tag[i] == recs) &
                                    (abs(trimmed.data$comb.x.movement[i]) < length.tolerance))
                                   
                                {reg.run[i]<-1}}}

            for (i in 1:(length(trimmed.data[,1])-1)){
                            if((is.na(reg.run[i])==FALSE) & (is.na(reg.run[i+1])==FALSE))
                                {reg.run[i+1]<-reg.run[i]+1
                                 reg.run[i]<-NA}
                                    }

            n.reg.run<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(n.reg.run)<-"mean length of regressive run"
            row.names(n.reg.run)<-(recs)

                for (i in 1:length(recs)){
                n.reg.run[i,]<-mean(reg.run[(trimmed.data$tag==paste("Rec", recordings[i])) & reg.run > min.reg.run], na.rm=T)
                            }

return(n.reg.run)

}#end function

This function extracts the length of regressive runs in pixles greater than some minimum

LenRegRun <- function(trimmed.data , recs = unique(trimmed.data$tag) , aois = unique(trimmed.data$aoi.tag[trimmed.data$aoi.tag != "NA"]) , ang.tolerance = 45,  length.tolerance = 100000 , min.reg.run = 20){

        if (ang.tolerance > 90 | ang.tolerance < 0) {stop(print("your ang.tolerence should be between 0.1 and 90 degrees"))}
        if (length.tolerance < 0) {stop(print("your length.tolerance should be greater than 0 pixals"))}
        if(missing(trimmed.data)) {stop("You need to enter a data frame")}
        if(names(trimmed.data)[1]!="tag")(stop("You need to enter a trimmed dataset, read the instructions again somthing has gone wrong"))

            deg.err<- tan(ang.tolerance*0.0174532925)

reg.run<-matrix(nrow=length(trimmed.data[,1]),ncol=1,NA)

           
            for (i in 1:length(trimmed.data[,1])){
                            if((is.na(trimmed.data$comb.x.movement[i]) == FALSE))
                                { if((trimmed.data$comb.x.movement[i] < 0) &
                                ((abs(trimmed.data$comb.y.movement[i])/abs(trimmed.data$comb.x.movement[i])) < deg.err) &
                                    any(trimmed.data$aoi.tag[i] == aois) &
                                    any(trimmed.data$tag[i] == recs) &
                                    (abs(trimmed.data$comb.x.movement[i]) < length.tolerance))
                                {reg.run[i]<-trimmed.data$comb.x.movement[i]}}}

            for (i in 1:(length(trimmed.data[,1])-1)){
                            if((is.na(reg.run[i])==FALSE) & (is.na(reg.run[i+1])==FALSE))
                                {reg.run[i+1]<-reg.run[i]+reg.run[i+1]
                                 reg.run[i]<-NA}
                                    }

            len.reg.run<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(len.reg.run)<-"length of forward saccadic run (px)"
            row.names(len.reg.run)<-(recs)

                for (i in 1:length(recs)){
                len.reg.run[i,]<-mean(reg.run[(trimmed.data$tag==paste("Rec", recordings[i])) & (abs(reg.run) > min.reg.run)], na.rm=T)
                            }

return(len.reg.run)

}#end function

This function looks for numbers of switches between specific AoIs

aois1<-c("Item6prompt", "Item5prompt")
aois2<-c( "Item6text", "Item5text")


### Need to make this work for specific recordings!

AoISwitch <- function(trimmed.data ,aois1 , aois2, recs = unique(trimmed.data$tag), max.fix.betw = 10, direction = "both"){

            switch.counter<-matrix(nrow = length(trimmed.data[,1]),ncol=1,0)
                n.steps <- 0
                value.holder <- 0

        if (direction == "both"){
            step <- 0; stored.value <- 0

            for (i in 1:length(trimmed.data[,1])) {
                if (trimmed.data$aoi.tag[i] == "NA") {step <- step+1}
                if (any(aois1 == stored.value) & any(aois2 == trimmed.data$aoi.tag[i]) & step < max.fix.betw) {switch.counter[i] <- switch.counter[i]+1}
                if (trimmed.data$aoi.tag[i] != "NA") {stored.value <- trimmed.data$aoi.tag[i]; step<-0}
                }
                       

            step <- 0; stored.value <- 0

                  for (i in length(trimmed.data[,1]):1) {
                if (trimmed.data$aoi.tag[i] == "NA") {step <- step+1}
                if (any(aois1 == stored.value) & any(aois2 == trimmed.data$aoi.tag[i]) & step < max.fix.betw) {switch.counter[i] <- switch.counter[i]+1}
                if (trimmed.data$aoi.tag[i] != "NA") {stored.value <- trimmed.data$aoi.tag[i]; step<-0}
                }}   

        if (direction == "to"){
            step <- 0; stored.value <- 0

            for (i in 1:length(trimmed.data[,1])) {
                if (trimmed.data$aoi.tag[i] == "NA") {step<-step+1}
                if (any(aois1 == stored.value) & any(aois2 == trimmed.data$aoi.tag[i]) & step < max.fix.betw) {switch.counter[i] <- switch.counter[i]+1}
                if (trimmed.data$aoi.tag[i] != "NA") {stored.value <- trimmed.data$aoi.tag[i]; step<-0}
                }}

        num.switch<-as.data.frame(matrix(nrow=length(recs), ncol=1, NA))
            names(num.switch)<-"Number os switches"
            row.names(num.switch)<-(recs)

                for (i in 1:length(recs)){
                num.switch[i,]<-sum(switch.counter[(trimmed.data$tag==paste("Rec", recordings[i]))], na.rm=T)
                            }

return(num.switch)
}#end function