Analisys of the Leap Motion experiment at FEUP

This document provides the analysis of the experiment conducted at UCP/CITAR comparing the movement of three devices - Mouse, LeapMotion (hand grab gesture), and Leap Motion (via Touchless app) - for pointing tasks.

We use Maczenzie's accuracy metrics to compare the devices.

PRODUCE_BULK_CHARTS = FALSE
PRODUCE_BULK_HIST_CHARTS = FALSE
PRODUCE_BULK_CHARTS_DEVICE_PLUS_USERID = FALSE

#install.packages(c("ggplot2", "doBy", "psych", "car", "xtable"))
require(ggplot2)
require(doBy)
require(psych)
require(car)
require(xtable)
source("functions.R")
library("grid")

# load metrics data
data <- read.csv(file="data/measures-feup.txt", head=TRUE, sep="")

# Users 0 and 5 did not complete the experiment
data <- data[ data$UserId != 5,]

# Only blocks <= 7
data <- data[ data$Block <= 7,]

# convert the column to factor and name the levels
data$Device <- as.factor(data$Device)

# Set the levels 
# LeapMotion=c(0),  Mouse=c(1), Touchpad=c(2), LeapMotionTouchless=c(4)
# LeapMotion does not exist in the dataset from the UCP experiment
levels(data$Device) <- list(Mouse=c(1), LeapMotionHandGrab=c(0), LeapMotionScreenTap=c(4))

# convert the block column to factor
data$Block <- factor(data$Block)

# In this analysis we use ErrorRateBinary, so we drop the ErrorRate column and change the column name ErrorRateBinary to ErrorRate
drops <- c("ErrorRate")
data<-data[,!(names(data) %in% drops)]
names(data)[names(data) == "ErrorRateBinary"] <- "ErrorRate"

# Compute the aggregate means for each variable.
# We agregate all values for the various circles
IVars <- c("Device", "Block", "Sequence", "UserId")
DVars <- c("Throughput", "ErrorRate", "MovementTime", "TRE", "TAC", "ODC", "MDC", "MV", "ME", "MO")
aggData <-aggregate(data[ ,DVars], data[ ,IVars], mean)
aggData$Block <- factor(aggData$Block)

Movement time as function of block

describe.MT.aggData <- describeBy(aggData$MovementTime, aggData[,c("Block")])
describe.MT.aggData <-do.call("rbind", describe.MT.aggData)
describe.MT.aggData <- cbind(Block=rownames(describe.MT.aggData), describe.MT.aggData)
describe.MT.aggData$Block <- factor(describe.MT.aggData$Block)

p <- ggplot(describe.MT.aggData, aes(x=Block, y=mean )) + 
    geom_point(stat="identity") +
    geom_line(aes(group=vars)) + 
    ylab("Movement time (seconds) with 95% conf int") +
    #xlab("Sequence") +
    #ggtitle("Throughput") +
    geom_errorbar(aes(ymin=mean-1.96*se, ymax=mean+1.96*se), colour="Black",
                  width=.2                    # Width of the error bars
                  ) +
    theme(legend.position="none") +
    theme() 
p

plot of chunk movement-time-block

p <- ggplot(aggData, aes_string(x="Block", y="MovementTime", group="Device", colour="Device" )) + 
            stat_summary(fun.y="mean", geom="line") + 
            stat_summary(fun.y="mean", geom="point", aes(shape=Device)) + 
            theme(legend.direction = "horizontal", legend.position = "top") +
            #ylab("Percentage (%)") +
            #xlab("Sequence") +
            #ggtitle(var) +
            scale_fill_brewer(palette="Set1") + 
            scale_colour_brewer(palette="Set1") +
            theme() #noop
p

plot of chunk movement-time-block

ggsave(file = paste("charts/","all-movementtime-block-lineplot.pdf", sep=""), 
               width=13/2.54, height=7/2.54, dpi=100)

Throughput as function of block

describe.T.aggData <- describeBy(aggData$Throughput, aggData[,c("Block")])
describe.T.aggData <-do.call("rbind", describe.T.aggData)
describe.T.aggData <- cbind(Block=rownames(describe.T.aggData), describe.T.aggData)
describe.T.aggData$Block <- factor(describe.T.aggData$Block)

p <- ggplot(describe.T.aggData, aes(x=Block, y=mean )) + 
    geom_point(stat="identity") +
    geom_line(aes(group=vars)) + 
    ylab("Throughput (bps) with 95% conf int") +
    #xlab("Sequence") +
    #ggtitle("Throughput") +
    geom_errorbar(aes(ymin=mean-1.96*se, ymax=mean+1.96*se), colour="Black",
                  width=.2                    # Width of the error bars
                  ) +
    theme(legend.position="none") +
    theme() 
p

plot of chunk throughput-block

p <- ggplot(aggData, aes_string(x="Block", y="Throughput", group="Device", colour="Device" )) + 
            stat_summary(fun.y="mean", geom="line") + 
            stat_summary(fun.y="mean", geom="point", aes(shape=Device)) + 
            theme(legend.direction = "horizontal", legend.position = "top") +
            #ylab("Percentage (%)") +
            #xlab("Sequence") +
            #ggtitle(var) +
            theme() #noop
p

plot of chunk throughput-block

ggsave(file = paste("charts/","all-throughput-block-lineplot.pdf", sep=""), 
               width=20/2.54, height=16/2.54, dpi=100)

Error rate as function of block

p <- ggplot(aggData, aes_string(x="Block", y="ErrorRate", group="Device", colour="Device" )) + 
            stat_summary(fun.y="mean", geom="line") + 
            stat_summary(fun.y="mean", geom="point", aes(shape=Device)) + 
            theme(legend.direction = "horizontal", legend.position = "top") +
            #ylab("Percentage (%)") +
            #xlab("Sequence") +
            #ggtitle(var) +
            theme() #noop
p

plot of chunk ErrorRate-block

ggsave(file = paste("charts/","all-throughput-block-lineplot.pdf", sep=""), 
               width=20/2.54, height=16/2.54, dpi=100)

Learning effect

To estimate the learning effect, we ran pairwise t-tests for average throughput per block (considering all devices) with a significance level of 5%:

#describeBy(data$MovementTime, data$Block)

# pairwise t-tests to determine learning effect blocks
p.t.test <- pairwise.t.test(aggData$Throughput, aggData$Block, paired=T, p.adjust.method="none")
diag(p.t.test$p.value) 
## [1] 1.025e-04 9.962e-07 3.124e-04 6.753e-01 9.812e-01 4.457e-05
diag(p.t.test$p.value) < 0.05
## [1]  TRUE  TRUE  TRUE FALSE FALSE  TRUE
# We will consider only blocks 4 to 8 in the rest of the analysis
filenameprefix <- "blocks4-7"
aggData.noLearn <- aggData[as.numeric(aggData$Block) > 3 & as.numeric(aggData$Block) < 8,]

# Drop unused block levels
aggData.noLearn$Block <- factor(aggData.noLearn$Block)

The results indicate a clear learning effect in blocks 1 to 3, but also indicate a significant different between blocks 6 and 7, suggesting that participants were still learning after block 6. However, in our following analysis we discard only blocks 1 to 3, since those represent the most significant learning effect.

Summary statistics

options(width = 200)

# describe the main variables and store in file
s<-describeBy(aggData.noLearn[, DVars], aggData.noLearn$Device, mat=FALSE, digits=2)
s <- do.call("rbind", s)

print(xtable(s), type = "html")
vars n mean sd median trimmed mad min max range skew kurtosis se
Mouse.Throughput 1 180.00 5.00 0.59 4.98 5.00 0.63 3.68 6.49 2.82 0.13 -0.47 0.04
Mouse.ErrorRate 2 180.00 0.04 0.05 0.00 0.03 0.00 0.00 0.20 0.20 1.17 1.22 0.00
Mouse.MovementTime 3 180.00 0.81 0.10 0.80 0.81 0.11 0.61 1.10 0.49 0.58 0.08 0.01
Mouse.TRE 4 180.00 0.10 0.08 0.07 0.10 0.10 0.00 0.33 0.33 0.47 -0.52 0.01
Mouse.TAC 5 180.00 1.61 0.34 1.60 1.60 0.30 0.80 2.60 1.80 0.32 0.05 0.03
Mouse.ODC 6 180.00 1.17 0.53 1.07 1.15 0.59 0.20 2.47 2.27 0.45 -0.72 0.04
Mouse.MDC 7 180.00 4.26 0.85 4.07 4.20 0.79 2.47 6.87 4.40 0.58 -0.02 0.06
Mouse.MV 8 180.00 22.62 7.08 21.73 22.27 7.82 9.51 48.22 38.72 0.53 0.16 0.53
Mouse.ME 9 180.00 20.09 5.56 19.90 19.91 5.78 8.99 41.02 32.03 0.40 0.19 0.41
Mouse.MO 10 180.00 -2.46 6.63 -2.29 -2.48 6.29 -18.62 21.81 40.43 0.26 0.72 0.49
LeapMotionHandGrab.Throughput 1 180.00 2.80 0.57 2.77 2.79 0.60 1.59 4.21 2.61 0.21 -0.67 0.04
LeapMotionHandGrab.ErrorRate 2 180.00 0.11 0.12 0.07 0.09 0.10 0.00 0.60 0.60 1.33 1.80 0.01
LeapMotionHandGrab.MovementTime 3 180.00 1.69 0.55 1.55 1.61 0.37 1.00 4.12 3.13 1.69 3.23 0.04
LeapMotionHandGrab.TRE 4 180.00 0.37 0.25 0.33 0.34 0.20 0.00 1.27 1.27 1.06 0.79 0.02
LeapMotionHandGrab.TAC 5 180.00 1.92 0.67 1.80 1.86 0.49 0.47 4.33 3.87 0.90 0.79 0.05
LeapMotionHandGrab.ODC 6 180.00 3.61 1.78 3.13 3.35 1.28 0.80 11.00 10.20 1.62 3.24 0.13
LeapMotionHandGrab.MDC 7 180.00 7.33 2.48 6.67 7.01 1.93 3.47 17.07 13.60 1.26 1.57 0.19
LeapMotionHandGrab.MV 8 180.00 26.40 13.37 22.27 24.32 8.52 8.53 88.30 79.77 1.68 3.37 1.00
LeapMotionHandGrab.ME 9 180.00 21.11 10.79 18.25 19.36 6.31 7.14 80.19 73.05 2.42 7.96 0.80
LeapMotionHandGrab.MO 10 180.00 -1.57 8.06 -1.97 -2.07 5.38 -25.27 39.38 64.65 1.29 5.43 0.60
LeapMotionScreenTap.Throughput 1 180.00 2.31 0.53 2.23 2.28 0.42 1.27 3.75 2.48 0.56 -0.08 0.04
LeapMotionScreenTap.ErrorRate 2 180.00 0.09 0.09 0.07 0.07 0.10 0.00 0.47 0.47 1.40 2.08 0.01
LeapMotionScreenTap.MovementTime 3 180.00 1.94 0.51 1.85 1.90 0.44 1.04 4.10 3.06 0.93 1.49 0.04
LeapMotionScreenTap.TRE 4 180.00 0.37 0.30 0.33 0.33 0.20 0.00 2.53 2.53 2.64 13.98 0.02
LeapMotionScreenTap.TAC 5 180.00 2.24 0.67 2.13 2.18 0.59 1.00 5.33 4.33 1.19 2.76 0.05
LeapMotionScreenTap.ODC 6 180.00 4.20 2.27 3.87 3.98 2.37 1.07 15.67 14.60 1.26 3.20 0.17
LeapMotionScreenTap.MDC 7 180.00 8.37 2.76 8.13 8.13 2.72 3.80 22.40 18.60 1.19 3.02 0.21
LeapMotionScreenTap.MV 8 180.00 21.87 7.01 20.08 20.89 4.93 11.89 51.25 39.36 1.71 3.76 0.52
LeapMotionScreenTap.ME 9 180.00 17.73 5.48 16.53 16.89 4.00 9.71 43.75 34.04 2.00 5.55 0.41
LeapMotionScreenTap.MO 10 180.00 -1.81 5.18 -1.99 -1.78 4.53 -22.26 14.59 36.85 -0.18 1.61 0.39
s <- cbind(Device=rownames(s), s)

write.table(s, file = paste("tables/", filenameprefix,"-measures-device-describeby.csv", sep=""), sep=",", row.names=FALSE)

remove(s)

Barplot for mean movement time

describeMetrics <- describeBy(aggData.noLearn[, c("MovementTime")], list(aggData.noLearn$Device))
a=cbind(describeMetrics$LeapMotionScreenTap, metric=rownames(describeMetrics$LeapMotionScreenTap))
a=cbind(a, Device="LeapMotionScreenTap")
b=cbind(describeMetrics$Mouse, metric=rownames(describeMetrics$Mouse))
b=cbind(b, Device="Mouse")
c=cbind(describeMetrics$LeapMotionHandGrab, metric=rownames(describeMetrics$LeapMotionHandGrab))
c=cbind(c, Device="LeapMotionHandGrab")
describeMetrics = rbind(a, b, c)


levels(describeMetrics$Device) <- list( Mouse=c("Mouse"), LeapMotionHandGrab=c("LeapMotionHandGrab"), LeapMotionScreenTap=c("LeapMotionScreenTap"))

describeMetrics
##   vars   n   mean     sd median trimmed    mad    min   max  range   skew kurtosis       se metric              Device
## 1    1 180 1.9404 0.5129 1.8534  1.8993 0.4430 1.0385 4.098 3.0596 0.9338  1.48741 0.038227      1 LeapMotionScreenTap
## 2    1 180 0.8123 0.1024 0.7977  0.8058 0.1056 0.6104 1.103 0.4926 0.5808  0.08339 0.007633      1               Mouse
## 3    1 180 1.6940 0.5509 1.5502  1.6075 0.3658 0.9961 4.124 3.1283 1.6879  3.23439 0.041063      1  LeapMotionHandGrab
# T.Test 
t.test(log(aggData.noLearn$MovementTime[aggData.noLearn$Device == "LeapMotionHandGrab"], 10), log(aggData.noLearn$MovementTime[aggData.noLearn$Device == "LeapMotionScreenTap"], 10), paired=T)
## 
##  Paired t-test
## 
## data:  log(aggData.noLearn$MovementTime[aggData.noLearn$Device == "LeapMotionHandGrab"],  and log(aggData.noLearn$MovementTime[aggData.noLearn$Device == "LeapMotionScreenTap"],     10) and     10)
## t = -6.095, df = 179, p-value = 6.539e-09
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.08398 -0.04290
## sample estimates:
## mean of the differences 
##                -0.06344
ggplot(describeMetrics, aes(x=Device, y=abs(mean), group=Device, colour=Device, fill=Device)) + 
    #stat_summary(fun.y="mean", geom="bar") + 
    geom_bar(stat="identity", width=.5, position = position_dodge(width=0.5)) +
    #geom_bar() +
    #coord_flip() +
    ylab("Mean movement time") +
    #xlab("") +
    geom_errorbar(aes(ymin=abs(mean)-1.96*abs(se), ymax=abs(mean)+1.96*abs(se)), colour="Black",
                  width=.2,                    # Width of the error bars
                  size = .1,
                  position=position_dodge(.5)) +
    #facet_wrap(  ~ metric,nrow=1, scales="free") +
    theme(legend.position="none", legend.direction="horizontal"
          #axis.text.x = element_blank()
          ) + 
    scale_fill_brewer(palette="Set1") + 
    scale_colour_brewer(palette="Set1") 
ggsave(file = paste("charts/",filenameprefix,"-mean-movementtime.pdf", sep=""), width=14/2.54, height=6/2.54, dpi=100)

plot of chunk chart-barplot-mean-movement-time

Histograms

plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist plot of chunk charts-bulk-hist

Boxplots

Lineplots

MO Over TRE

s <- summaryBy(ErrorRate+TRE+TAC+MDC+ODC+MV+ME+MO+MovementTime+Throughput~Device, 
               data=aggData.noLearn,
               FUN=c(mean,sd))
# plot the movement offset over the TRE for each device
p <- ggplot(s, aes(x=TRE.mean, y=abs(MO.mean), group=Device, colour=Device )) +
    geom_point(size=5, aes(shape=Device)) + 
    #coord_cartesian(xlim = c(0, 0.4), ylim=c(0, 8)) + 
    ylab("Movement offset (pixels)") +
    xlab("Target Re-Entry") +
    theme(legend.position=c(0.55,0.9), legend.direction="horizontal") +
    theme()
p

plot of chunk chart-MO-over-TRE

ggsave(file = paste("charts/",filenameprefix,"-MO-TRE.pdf", sep=""), width=14/2.54, height=7/2.54, dpi=100)

Throughput and Error rate

# plot the throughput and ErrorRate

describe <- describeBy(aggData.noLearn$Throughput, list(aggData.noLearn$Device))
describe<-do.call("rbind",describe)
describe <- cbind(Device=rownames(describe), describe)
levels(describe$Device) <- list( Mouse=c("Mouse"), LeapMotionHandGrab=c("LeapMotionHandGrab"), LeapMotionScreenTap=c("LeapMotionScreenTap"))
p1 <- ggplot(describe, aes(x=Device, y=mean, colour=Device, fill=Device )) + 
    geom_bar(stat="identity") +
    ylab("BPS") +
    xlab("Throughput") +
    #ggtitle("Throughput") +
    geom_errorbar(aes(ymin=mean-1.96*se, ymax=mean+1.96*se), colour="Black",
                  width=.2,                    # Width of the error bars
                  position=position_dodge(.9)) +
    theme(
        plot.margin=unit(c(10,1,1,1),"mm"),
        legend.position="none", 
        #axis.text.x = element_text(angle = 20, hjust = 1),
        axis.text.x=element_blank()) +
    scale_fill_brewer(palette="Set1") + 
    scale_colour_brewer(palette="Set1") +
    theme() 

#ggsave(file = paste("charts/",filenameprefix,"-Throughput.pdf",sep=""), width=20/2.54, height=16/2.54, dpi=100)

describe <- describeBy(aggData.noLearn$ErrorRate, list(aggData.noLearn$Device))
describe<-do.call("rbind",describe)
describe <- cbind(Device=rownames(describe), describe)
levels(describe$Device) <- list( Mouse=c("Mouse"), LeapMotionHandGrab=c("LeapMotionHandGrab"), LeapMotionScreenTap=c("LeapMotionScreenTap"))

p2 <- ggplot(describe, aes(x=Device, y=mean*100, colour=Device, fill=Device )) + 
    geom_bar(stat="identity") +
    ylab("Percent.(%)") +
    xlab("ErrorRate") +
    #ggtitle("ErrorRate") +
    geom_errorbar(aes(ymin=100*(mean-1.96*se), ymax=100*(mean+1.96*se)), colour="Black",
                  width=.2,                    # Width of the error bars
                  position=position_dodge(.9)) +

    theme(
         plot.margin=unit(c(10,1,1,1),"mm"),
         legend.position=c(-0.1,1.07), 
          legend.direction="horizontal", 
          #axis.text.x = element_text(angle = 20, hjust = 1),
          axis.text.x=element_blank()) +
    scale_fill_brewer(palette="Set1") + 
    scale_colour_brewer(palette="Set1") +
    theme() 

#pdf(file = paste("charts/",filenameprefix,"-Throughput+ErrorRate.pdf",sep=""), width=20/2.54, height=16/2.54)
pdf(file = paste("charts/",filenameprefix,"-Throughput+ErrorRate-small.pdf",sep=""), width=16/2.54, height=9/2.54)
multiplot(p1, p2, cols=2)
dev.off()
## pdf 
##   2
p1
p2

plot of chunk chart-Throughput-and-ErrorRate plot of chunk chart-Throughput-and-ErrorRate

Barplots for metrics

describeMetrics <- describeBy(aggData.noLearn[, c("TRE","TAC","MDC","ODC","MV","ME","MO")], list(aggData.noLearn$Device))
a=cbind(describeMetrics$LeapMotionScreenTap, metric=rownames(describeMetrics$LeapMotionScreenTap))
a=cbind(a, Device="LeapMotionScreenTap")
b=cbind(describeMetrics$Mouse, metric=rownames(describeMetrics$Mouse))
b=cbind(b, Device="Mouse")
c=cbind(describeMetrics$LeapMotionHandGrab, metric=rownames(describeMetrics$LeapMotionHandGrab))
c=cbind(c, Device="LeapMotionHandGrab")
describeMetrics = rbind(a, b, c)
describeMetrics$metric <- factor(describeMetrics$metric, levels=c("TRE", "TAC", "MDC", "ODC", "MV", "ME", "MO"))

levels(describeMetrics$Device) <- list( Mouse=c("Mouse"), LeapMotionHandGrab=c("LeapMotionHandGrab"), LeapMotionScreenTap=c("LeapMotionScreenTap"))

ggplot(describeMetrics, aes(x=Device, y=abs(mean), group=Device, colour=Device, fill=Device)) + 
    #stat_summary(fun.y="mean", geom="bar") + 
    geom_bar(stat="identity", width=.5, position = position_dodge(width=0.5)) +
    #geom_bar() +
    #coord_flip() +
    ylab("Mean") +
    xlab("") +
    geom_errorbar(aes(ymin=abs(mean)-1.96*abs(se), ymax=abs(mean)+1.96*abs(se)), colour="Black",
                  width=.2,                    # Width of the error bars
                  size = .1,
                  position=position_dodge(.5)) +
    facet_wrap(  ~ metric,nrow=1, scales="free") +
    theme(legend.position=c(.5, -0.1), legend.direction="horizontal", 
          axis.text.x = element_blank()) + 
    scale_fill_brewer(palette="Set1") + 
    scale_colour_brewer(palette="Set1") 
ggsave(file = paste("charts/",filenameprefix,"-metrics.pdf", sep=""), width=30/2.54, height=6/2.54, dpi=100)

plot of chunk chart-barplots

Correlations

vars <- c("Throughput", "TRE", "TAC", "ODC", "MDC", "MV", "ME", "MO")


print(xtable(round(cor(aggData.noLearn[, vars]), 2)), type = "html")
Throughput TRE TAC ODC MDC MV ME MO
Throughput 1.00 -0.54 -0.48 -0.70 -0.75 -0.11 0.01 -0.07
TRE -0.54 1.00 0.72 0.81 0.74 0.36 0.24 0.13
TAC -0.48 0.72 1.00 0.70 0.72 0.30 0.17 0.14
ODC -0.70 0.81 0.70 1.00 0.79 0.39 0.28 0.05
MDC -0.75 0.74 0.72 0.79 1.00 0.18 0.07 0.07
MV -0.11 0.36 0.30 0.39 0.18 1.00 0.94 0.08
ME 0.01 0.24 0.17 0.28 0.07 0.94 1.00 0.00
MO -0.07 0.13 0.14 0.05 0.07 0.08 0.00 1.00

Analysis of Variance - Differences between devices

Analysis of variance of the throughput for the three devices showed significant differences

# Anova for Throughput
aov.Throughput <- aov(Throughput~Device+Error(factor(UserId) / Device), data=aggData.noLearn)
#aov.Throughput <- aov(Throughput~Device, data=aggData.noLearn)
#aov.Throughput
summary(aov.Throughput)
## 
## Error: factor(UserId)
##           Df Sum Sq Mean Sq F value Pr(>F)
## Residuals  8   74.3    9.28               
## 
## Error: factor(UserId):Device
##           Df Sum Sq Mean Sq F value  Pr(>F)    
## Device     2    742     371     134 9.9e-11 ***
## Residuals 16     44       3                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Error: Within
##            Df Sum Sq Mean Sq F value Pr(>F)
## Residuals 513   52.9   0.103
# pairwise comparisons, adjusting p-value
# all devices are significantly different from each other, in terms of throughput
TukeyHSD(aov.Throughput)
## Error: no applicable method for 'TukeyHSD' applied to an object of class "c('aovlist', 'listof')"
# Anova for TAC
aov.TAC <- aov(TAC~Device, data=aggData.noLearn)
#aov.TAC
summary(aov.TAC)
##              Df Sum Sq Mean Sq F value Pr(>F)    
## Device        2   35.8   17.92    53.1 <2e-16 ***
## Residuals   537  181.3    0.34                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.TAC)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = TAC ~ Device, data = aggData.noLearn)
## 
## $Device
##                                          diff    lwr    upr p adj
## LeapMotionHandGrab-Mouse               0.3122 0.1683 0.4562     0
## LeapMotionScreenTap-Mouse              0.6311 0.4871 0.7751     0
## LeapMotionScreenTap-LeapMotionHandGrab 0.3189 0.1749 0.4629     0
# T.Test 
t.TAC<-t.test(aggData.noLearn$TAC[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$TAC[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.TAC
## 
##  Paired t-test
## 
## data:  aggData.noLearn$TAC[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$TAC[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = -5.338, df = 179, p-value = 2.819e-07
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.4368 -0.2010
## sample estimates:
## mean of the differences 
##                 -0.3189
# Anova for TRE
aov.TRE <- aov(TRE~Device, data=aggData.noLearn)
#aov.TRE
summary(aov.TRE)
##              Df Sum Sq Mean Sq F value Pr(>F)    
## Device        2   8.46    4.23    78.4 <2e-16 ***
## Residuals   537  28.99    0.05                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.TRE)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = TRE ~ Device, data = aggData.noLearn)
## 
## $Device
##                                             diff      lwr    upr  p adj
## LeapMotionHandGrab-Mouse               0.2651852  0.20762 0.3227 0.0000
## LeapMotionScreenTap-Mouse              0.2659259  0.20836 0.3235 0.0000
## LeapMotionScreenTap-LeapMotionHandGrab 0.0007407 -0.05682 0.0583 0.9995
# T.Test 
t.TRE<-t.test(aggData.noLearn$TRE[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$TRE[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.TRE
## 
##  Paired t-test
## 
## data:  aggData.noLearn$TRE[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$TRE[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = -0.0317, df = 179, p-value = 0.9748
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.04690  0.04541
## sample estimates:
## mean of the differences 
##              -0.0007407
# Anova for MDC
aov.MDC <- aov(MDC~Device, data=aggData.noLearn)
#aov.MDC
summary(aov.MDC)
##              Df Sum Sq Mean Sq F value Pr(>F)    
## Device        2   1647     824     170 <2e-16 ***
## Residuals   537   2600       5                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.MDC)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = MDC ~ Device, data = aggData.noLearn)
## 
## $Device
##                                         diff    lwr   upr p adj
## LeapMotionHandGrab-Mouse               3.073 2.5282 3.618     0
## LeapMotionScreenTap-Mouse              4.114 3.5690 4.659     0
## LeapMotionScreenTap-LeapMotionHandGrab 1.041 0.4956 1.586     0
t.MDC<-t.test(aggData.noLearn$MDC[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$MDC[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.MDC
## 
##  Paired t-test
## 
## data:  aggData.noLearn$MDC[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$MDC[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = -4.507, df = 179, p-value = 1.185e-05
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -1.4964 -0.5851
## sample estimates:
## mean of the differences 
##                  -1.041
# Anova for ODC
aov.ODC <- aov(ODC~Device, data=aggData.noLearn)
#aov.ODC
summary(aov.ODC)
##              Df Sum Sq Mean Sq F value Pr(>F)    
## Device        2    926     463     161 <2e-16 ***
## Residuals   537   1543       3                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.ODC)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = ODC ~ Device, data = aggData.noLearn)
## 
## $Device
##                                          diff    lwr   upr p adj
## LeapMotionHandGrab-Mouse               2.4367 2.0167 2.857 0.000
## LeapMotionScreenTap-Mouse              3.0256 2.6056 3.446 0.000
## LeapMotionScreenTap-LeapMotionHandGrab 0.5889 0.1689 1.009 0.003
t.ODC<-t.test(aggData.noLearn$ODC[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$ODC[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.ODC
## 
##  Paired t-test
## 
## data:  aggData.noLearn$ODC[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$ODC[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = -3.177, df = 179, p-value = 0.001752
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.9546 -0.2231
## sample estimates:
## mean of the differences 
##                 -0.5889
# Anova for MV
aov.MV <- aov(MV~Device, data=aggData.noLearn)
#aov.MV
summary(aov.MV)
##              Df Sum Sq Mean Sq F value  Pr(>F)    
## Device        2   2121    1060    11.4 1.4e-05 ***
## Residuals   537  49788      93                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.MV)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = MV ~ Device, data = aggData.noLearn)
## 
## $Device
##                                           diff    lwr    upr  p adj
## LeapMotionHandGrab-Mouse                3.7806  1.395  6.166 0.0006
## LeapMotionScreenTap-Mouse              -0.7462 -3.132  1.639 0.7427
## LeapMotionScreenTap-LeapMotionHandGrab -4.5268 -6.912 -2.141 0.0000
t.MV<-t.test(aggData.noLearn$MV[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$MV[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.MV
## 
##  Paired t-test
## 
## data:  aggData.noLearn$MV[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$MV[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = 4.222, df = 179, p-value = 3.844e-05
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  2.411 6.642
## sample estimates:
## mean of the differences 
##                   4.527
# Anova for ME
aov.ME <- aov(ME~Device, data=aggData.noLearn)
#aov.ME
summary(aov.ME)
##              Df Sum Sq Mean Sq F value  Pr(>F)    
## Device        2   1083     541    9.16 0.00012 ***
## Residuals   537  31735      59                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(aov.ME)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = ME ~ Device, data = aggData.noLearn)
## 
## $Device
##                                          diff     lwr     upr  p adj
## LeapMotionHandGrab-Mouse                1.011 -0.8935  2.9154 0.4257
## LeapMotionScreenTap-Mouse              -2.368 -4.2721 -0.4631 0.0101
## LeapMotionScreenTap-LeapMotionHandGrab -3.379 -5.2830 -1.4741 0.0001
t.ME<-t.test(aggData.noLearn$ME[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$ME[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.ME
## 
##  Paired t-test
## 
## data:  aggData.noLearn$ME[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$ME[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = 3.828, df = 179, p-value = 0.0001785
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  1.637 5.120
## sample estimates:
## mean of the differences 
##                   3.379
# Anova for MO
aov.MO <- aov(MO~Device, data=aggData.noLearn)
#aov.MO
summary(aov.MO)
##              Df Sum Sq Mean Sq F value Pr(>F)
## Device        2     77    38.3    0.85   0.43
## Residuals   537  24279    45.2
TukeyHSD(aov.MO)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = MO ~ Device, data = aggData.noLearn)
## 
## $Device
##                                           diff     lwr   upr  p adj
## LeapMotionHandGrab-Mouse                0.8913 -0.7744 2.557 0.4199
## LeapMotionScreenTap-Mouse               0.6498 -1.0159 2.316 0.6299
## LeapMotionScreenTap-LeapMotionHandGrab -0.2415 -1.9073 1.424 0.9380
t.MO<-t.test(aggData.noLearn$MO[aggData.noLearn$Device == "LeapMotionHandGrab"], aggData.noLearn$MO[aggData.noLearn$Device == "LeapMotionScreenTap"], paired=T)
t.MO
## 
##  Paired t-test
## 
## data:  aggData.noLearn$MO[aggData.noLearn$Device == "LeapMotionHandGrab"] and aggData.noLearn$MO[aggData.noLearn$Device == "LeapMotionScreenTap"]
## t = 0.335, df = 179, p-value = 0.738
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -1.181  1.664
## sample estimates:
## mean of the differences 
##                  0.2415

MDC Over ODC

s <- summaryBy(ErrorRate+TRE+TAC+MDC+ODC+MV+ME+MO+MovementTime+Throughput~Device, 
               data=aggData.noLearn,
               FUN=c(mean,sd))
# plot the movement offset over the TRE for each device
p <- ggplot(s, aes(x=MDC.mean, y=abs(ODC.mean), group=Device, colour=Device )) +
    geom_point(size=5, aes(shape=Device)) + 
    #coord_cartesian(xlim = c(0, 0.4), ylim=c(0, 8)) + 
    ylab("Orthogonal direction change (pixels)") +
    xlab("Movement direction change (pixels)") +
    theme(legend.position=c(0.55,0.9), legend.direction="horizontal") +
    theme()
p

plot of chunk chart-MDC-over-ODC

ggsave(file = paste("charts/",filenameprefix,"-MDC-ODC.pdf", sep=""), width=14/2.54, height=7/2.54, dpi=100)