Loading and preparing data for analysis
data = read.table("XP2CursorTransferFunction_logs.csv", header=TRUE, sep=",")
data = data %>% arrange(participantId, func, block, series, trialId)
# filtering first trial of each set, because we don't know where in the scene, the cursor come from.
# then mutate some data to adapt to our stats scripts
data = data %>%
filter(trialId > 1) %>%
mutate(distance = ifelse(longDist == "True", "long", "short")) %>%
mutate(position = ifelse(target > 4, "far", "close")) %>%
arrange(participantId, func, block, distance, position)
# aggregating by set of trials, and computing error rate:
dataErrorMeans = data %>%
group_by(participantId, func, block, distance, position) %>%
summarize(errorRate = computeErrorRate(success))
# same aggregation as above, but we compute the mean time:
dataSuccessAggr = data %>%
filter(success == "True") %>%
group_by(participantId, func, block, distance, position) %>%
summarize(meanFinalTimer = mean(finalTimer))
# aggregated data, with mean time and error rate in the same data table:
dataAggr = left_join(dataSuccessAggr, dataErrorMeans, by = c("participantId", "func", "block", "distance", "position"))
# useful if we exclude block 1 in some analysis:
dataAggrBlock23 = dataAggr %>% filter(block > 1)
techniques = unique(data$func)
blocks = unique(data$block)
distances = unique(data$distance)
positions = unique(data$position)
Selection time
Effect of blocks on selection time
Check the normality of data
data.long = melt(dataAggr, id = c("meanFinalTimer", "participantId", "func", "block", "distance", "position"))
data.long$func = factor(data.long$func)
data.long$block = factor(data.long$block)
data.long$distance = factor(data.long$distance)
data.long$position = factor(data.long$position)
m <- aov(meanFinalTimer ~ func*block*distance*position, data=data.long)
pander(normalCheck(m))
Shapiro-Wilk normality test
data: res W = 0.92556, p-value = 1.259e-11
Shapiro-Wilk normality test: res
0.9256 |
1.259e-11 * * * |
Selection time does not follow a normal distribution.
Analysis with all blocks
Mean time per fonction

1_Prop |
2.791502 |
2_Lerp |
2.421525 |
3_Lerp_BetterProp |
2.386873 |
Post-hoc analysis with Bonferroni correction
attach(datatr)
pw <- pairwise.t.test(meanFinalTimer, interaction(func), p.adj = "bonferroni")
detach(datatr)
kable(pw$p.value)
2_Lerp |
0.8353236 |
NA |
3_Lerp_BetterProp |
0.0542808 |
0.5937127 |
Mean time per fonction * distance

1_Prop |
long |
3.518208 |
2_Lerp |
long |
2.956052 |
3_Lerp_BetterProp |
long |
2.977169 |
1_Prop |
short |
2.064797 |
2_Lerp |
short |
1.886999 |
3_Lerp_BetterProp |
short |
1.796578 |
Post-hoc analysis with Bonferroni correction
attach(datatr)
pw <- pairwise.t.test(meanFinalTimer, interaction(func,distance), p.adj = "bonferroni")
detach(datatr)
kable(pw$p.value)
2_Lerp.long |
1.0000000 |
NA |
NA |
NA |
NA |
3_Lerp_BetterProp.long |
0.5498107 |
1 |
NA |
NA |
NA |
1_Prop.short |
0.0000000 |
0 |
8e-07 |
NA |
NA |
2_Lerp.short |
0.0000000 |
0 |
0e+00 |
1.0000000 |
NA |
3_Lerp_BetterProp.short |
0.0000000 |
0 |
0e+00 |
0.6671455 |
1 |
Mean time per fonction * position

1_Prop |
close |
1.863821 |
2_Lerp |
close |
2.079784 |
3_Lerp_BetterProp |
close |
1.895889 |
1_Prop |
far |
3.719183 |
2_Lerp |
far |
2.763267 |
3_Lerp_BetterProp |
far |
2.877857 |
Post-hoc analysis with Bonferroni correction
attach(datatr)
pw <- pairwise.t.test(meanFinalTimer, interaction(func,position), p.adj = "bonferroni")
detach(datatr)
kable(pw$p.value)
2_Lerp.close |
0.4879705 |
NA |
NA |
NA |
NA |
3_Lerp_BetterProp.close |
1.0000000 |
0.5499846 |
NA |
NA |
NA |
1_Prop.far |
0.0000000 |
0.0000000 |
0e+00 |
NA |
NA |
2_Lerp.far |
0.0000001 |
0.0023068 |
1e-07 |
0.0011946 |
NA |
3_Lerp_BetterProp.far |
0.0000002 |
0.0033946 |
2e-07 |
0.0007942 |
1 |
Error rate
Check the normality of data
data.long = melt(dataAggr, id = c("errorRate", "participantId", "func", "block", "distance", "position"))
data.long$func = factor(data.long$func)
data.long$block = factor(data.long$block)
data.long$distance = factor(data.long$distance)
data.long$position = factor(data.long$position)
m <- aov(errorRate ~ func*block*distance*position, data=data.long)
pander(normalCheck(m))
Shapiro-Wilk normality test
data: res W = 0.90167, p-value = 1.168e-13
Shapiro-Wilk normality test: res
0.9017 |
1.168e-13 * * * |
Error rate does not follow a normal distribution.
Effect of blocks on error rate
Running ANOVA on ART
m = art(errorRate ~ block + (1|participantId), data=data.long)
kable(anova(m))
block |
block |
0.6502996 |
2 |
313 |
0.5225931 |
Analysis with all blocks
Running ANOVA on ART
m = art(errorRate ~ func*distance*position + (1|participantId), data=data.long)
kable(anova(m))
## Warning in optwrap(optimizer, devfun, getStart(start, rho$lower, rho$pp), :
## convergence code 3 from bobyqa: bobyqa -- a trust region step failed to
## reduce q
func |
func |
8.132635 |
2 |
304 |
0.0003625 |
distance |
distance |
3.133194 |
1 |
304 |
0.0777156 |
position |
position |
29.650015 |
1 |
304 |
0.0000001 |
func:distance |
func:distance |
1.518695 |
2 |
304 |
0.2206543 |
func:position |
func:position |
12.884696 |
2 |
304 |
0.0000043 |
distance:position |
distance:position |
9.802322 |
1 |
304 |
0.0019124 |
func:distance:position |
func:distance:position |
4.927234 |
2 |
304 |
0.0078357 |
Error rate per fonction

1_Prop |
7.407407 |
2_Lerp |
3.703704 |
3_Lerp_BetterProp |
4.629630 |
Post-hoc analysis with Bonferroni correction
pw = lsmeans(artlm(m, "func"), pairwise ~ func, adjust = "bonferroni")
## Loading required namespace: lmerTest
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
1_Prop - 2_Lerp |
48.29630 |
11.97627 |
19.0000000 |
4.032667 |
0.0021333 |
1_Prop - 3_Lerp_BetterProp |
23.59259 |
11.97627 |
0.3877551 |
1.969945 |
1.0000000 |
2_Lerp - 3_Lerp_BetterProp |
-24.70370 |
11.97627 |
0.3877551 |
-2.062721 |
1.0000000 |
# attach(data.long)
# pw <- pairwise.t.test(errorRate, interaction(func), p.adj = "bonferroni")
# detach(data.long)
# kable(pw$p.value)
Error rate per fonction * distance

1_Prop |
long |
6.481482 |
2_Lerp |
long |
4.398148 |
3_Lerp_BetterProp |
long |
5.555556 |
1_Prop |
short |
8.333333 |
2_Lerp |
short |
3.009259 |
3_Lerp_BetterProp |
short |
3.703704 |
Post-hoc analysis with Bonferroni correction
datafilt.long = data.long %>% filter(distance == "short")
m = art(errorRate ~ func*position + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "func"), pairwise ~ func, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
1_Prop - 2_Lerp |
23.074074 |
8.116009 |
37.000000 |
2.8430320 |
0.0216999 |
1_Prop - 3_Lerp_BetterProp |
16.981482 |
8.116009 |
0.755102 |
2.0923438 |
1.0000000 |
2_Lerp - 3_Lerp_BetterProp |
-6.092593 |
8.116009 |
0.755102 |
-0.7506882 |
1.0000000 |
datafilt.long = data.long %>% filter(distance == "long")
m = art(errorRate ~ func*position + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "func"), pairwise ~ func, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
1_Prop - 2_Lerp |
18.379630 |
8.408903 |
37.000000 |
2.1857346 |
0.1057184 |
1_Prop - 3_Lerp_BetterProp |
3.814815 |
8.408903 |
0.755102 |
0.4536638 |
1.0000000 |
2_Lerp - 3_Lerp_BetterProp |
-14.564815 |
8.408903 |
0.755102 |
-1.7320708 |
1.0000000 |
attach(data.long)
pw <- pairwise.t.test(errorRate, interaction(func,distance), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
2_Lerp.long |
1.0000000 |
NA |
NA |
NA |
NA |
3_Lerp_BetterProp.long |
1.0000000 |
1.0000000 |
NA |
NA |
NA |
1_Prop.short |
1.0000000 |
0.3652646 |
1 |
NA |
NA |
2_Lerp.short |
0.7014988 |
1.0000000 |
1 |
0.0359324 |
NA |
3_Lerp_BetterProp.short |
1.0000000 |
1.0000000 |
1 |
0.1225898 |
1 |
Error rate per fonction * position

1_Prop |
close |
3.009259 |
2_Lerp |
close |
3.472222 |
3_Lerp_BetterProp |
close |
1.620370 |
1_Prop |
far |
11.805556 |
2_Lerp |
far |
3.935185 |
3_Lerp_BetterProp |
far |
7.638889 |
Post-hoc analysis with Bonferroni correction
datafilt.long = data.long %>% filter(position == "close")
m = art(errorRate ~ func*distance + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "func"), pairwise ~ func, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
1_Prop - 2_Lerp |
3.296296 |
7.51097 |
37.000000 |
0.4388643 |
1 |
1_Prop - 3_Lerp_BetterProp |
13.148148 |
7.51097 |
0.755102 |
1.7505260 |
1 |
2_Lerp - 3_Lerp_BetterProp |
9.851852 |
7.51097 |
0.755102 |
1.3116618 |
1 |
datafilt.long = data.long %>% filter(position == "far")
m = art(errorRate ~ func*distance + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "func"), pairwise ~ func, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
1_Prop - 2_Lerp |
26.296296 |
8.201125 |
37.000000 |
3.2064253 |
0.0083108 |
1_Prop - 3_Lerp_BetterProp |
6.314815 |
8.201125 |
0.755102 |
0.7699937 |
1.0000000 |
2_Lerp - 3_Lerp_BetterProp |
-19.981482 |
8.201125 |
0.755102 |
-2.4364316 |
0.9235550 |
attach(data.long)
pw <- pairwise.t.test(errorRate, interaction(func,position), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
2_Lerp.close |
1.0000000 |
NA |
NA |
NA |
NA |
3_Lerp_BetterProp.close |
1.0000000 |
1.0000000 |
NA |
NA |
NA |
1_Prop.far |
0.0000024 |
0.0000099 |
0.0000000 |
NA |
NA |
2_Lerp.far |
1.0000000 |
1.0000000 |
1.0000000 |
0.0000377 |
NA |
3_Lerp_BetterProp.far |
0.0765744 |
0.1744182 |
0.0043312 |
0.1744182 |
0.3713011 |
Preferences

1_Prop |
0 |
2_Lerp |
5 |
3_Lerp_BetterProp |
4 |