data = read.table("https://cs.uwaterloo.ca/~gcasiez/cs889f18/exercises/ForceEdgeStudy1.csv", header=TRUE, sep=",")
#data = read.table("ForceEdgeStudy1.csv", header=TRUE, sep=",")
Keep trials where success == “True”
data_filtered = data %>% filter(success == "True")
Aggregation trials by participant, task, technique, block, distance.
data_aggr = data_filtered %>%
group_by(participant, task, technique, block, distance) %>% # Group data by factors
summarise(time = mean(time)) # compute means for time
Convert data to long format
data.long = melt(data_aggr, id = c("time","participant","task","technique","block","distance"))
Define factors
data.long$task = factor(data.long$task)
data.long$technique = factor(data.long$technique)
data.long$block = factor(data.long$block)
data.long$distance = factor(data.long$distance)
ANOVA
anova = ezANOVA(data.long, dv=.(time), wid=.(participant), within=.(task,technique,block,distance), detailed=TRUE)
# kable(anova$ANOVA)
# kable(anova$`Mauchly's Test for Sphericity`)
# kable(anova$`Sphericity Corrections`)
kable(anova_apa(anova, sph_corr ="gg", print=FALSE))
effect | text |
---|---|
(Intercept) | F(1, 15) = 444.97, p < .001, petasq = .97 |
task | F(1, 15) = 98.94, p < .001, petasq = .87 |
technique | F(1, 15) = 119.27, p < .001, petasq = .89 |
block | F(2, 30) = 62.09, p < .001, petasq = .81 |
distance | F(1.16, 17.46) = 146.79, p < .001, petasq = .91 |
task:technique | F(1, 15) = 72.79, p < .001, petasq = .83 |
task:block | F(2, 30) = 19.76, p < .001, petasq = .57 |
technique:block | F(1.47, 21.98) = 0.83, p = .416, petasq = .05 |
task:distance | F(2, 30) = 62.42, p < .001, petasq = .81 |
technique:distance | F(2, 30) = 117.35, p < .001, petasq = .89 |
block:distance | F(4, 60) = 6.48, p < .001, petasq = .30 |
task:technique:block | F(2, 30) = 5.43, p = .010, petasq = .27 |
task:technique:distance | F(1.11, 16.72) = 44.73, p < .001, petasq = .75 |
task:block:distance | F(4, 60) = 5.29, p = .001, petasq = .26 |
technique:block:distance | F(4, 60) = 3.68, p = .010, petasq = .20 |
task:technique:block:distance | F(4, 60) = 5.00, p = .002, petasq = .25 |
We observe a significant main effect of block F(2, 30) = 62.09, p < .001, petasq = .81, indicating there is a learning of fatigue effect. Let’s run post-hoc analysis to understand where it comes from.
kable(aggregate( time~block, data.long, mean ))
block | time |
---|---|
1 | 6.631972 |
2 | 5.506011 |
3 | 5.231864 |
Posthoc comparisons with Bonferroni corrections
attach(data.long)
pw <- pairwise.t.test(time, interaction(block), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
1 | 2 | |
---|---|---|
2 | 0.0076355 | NA |
3 | 0.0005419 | 1 |
Pairwise comparisons showed a significant decrease (p < 0.0001) in the trial time between the first block and the two remaining, due to a familiarization with the experimental procedure. As we are concerned with user performance after familiarization, the first block was removed from subsequent analysis.
data = read.table("https://cs.uwaterloo.ca/~gcasiez/cs889f18/exercises/ForceEdgeStudy1.csv", header=TRUE, sep=",")
#data = read.table("ForceEdgeStudy1.csv", header=TRUE, sep=",")
data_filtered = data %>% filter(success == "True" & block > 1)
Aggregate by participant, task, technique, block, distance.
data_aggr = data_filtered %>%
group_by(participant, task, technique, block, distance) %>% # Group data by factors
summarise(time = mean(time)) # compute means for time
Convert data to long format
data.long = melt(data_aggr, id = c("time","participant","task","technique","block","distance"))
Provide factors
data.long$task = factor(data.long$task)
data.long$technique = factor(data.long$technique)
data.long$block = factor(data.long$block)
data.long$distance = factor(data.long$distance)
ANOVA
anova = ezANOVA(data.long, dv=.(time), wid=.(participant), within=.(task,technique,block,distance), detailed=TRUE)
## Warning: Converting "participant" to factor for ANOVA.
# kable(anova$ANOVA)
# kable(anova$`Mauchly's Test for Sphericity`)
# kable(anova$`Sphericity Corrections`)
kable(anova_apa(anova, sph_corr ="gg", print=FALSE))
effect | text |
---|---|
(Intercept) | F(1, 15) = 411.10, p < .001, petasq = .96 |
task | F(1, 15) = 61.45, p < .001, petasq = .80 |
technique | F(1, 15) = 121.63, p < .001, petasq = .89 |
block | F(1, 15) = 5.61, p = .032, petasq = .27 |
distance | F(1.15, 17.31) = 108.62, p < .001, petasq = .88 |
task:technique | F(1, 15) = 42.72, p < .001, petasq = .74 |
task:block | F(1, 15) = 0.55, p = .469, petasq = .04 |
technique:block | F(1, 15) = 0.06, p = .808, petasq < .01 |
task:distance | F(1.31, 19.72) = 34.25, p < .001, petasq = .70 |
technique:distance | F(2, 30) = 78.21, p < .001, petasq = .84 |
block:distance | F(2, 30) = 1.75, p = .191, petasq = .10 |
task:technique:block | F(1, 15) = 0.00, p = .953, petasq < .01 |
task:technique:distance | F(1.18, 17.69) = 19.85, p < .001, petasq = .57 |
task:block:distance | F(2, 30) = 0.73, p = .492, petasq = .05 |
technique:block:distance | F(2, 30) = 2.91, p = .070, petasq = .16 |
task:technique:block:distance | F(1.41, 21.11) = 0.06, p = .882, petasq < .01 |
Repeated measures ANOVA showed a significant main effect of task (F(1, 15) = 61.45, p < .001, petasq = .80), technique (F(1, 15) = 121.63, p < .001, petasq = .89), distance (F(1.15, 17.31) = 108.62, p < .001, petasq = .88) and significant task × technique (F(1, 15) = 42.72, p < .001, petasq = .74), task × distance (F(1.31, 19.72) = 34.25, p < .001, petasq = .70), technique × distance (F(2, 30) = 78.21, p < .001, petasq = .84) and task × technique × distance (F(1.18, 17.69) = 19.85, p < .001, petasq = .57) interactions on trial time.
kable(aggregate( time~task, data.long, mean ))
task | time |
---|---|
Move | 6.363630 |
Select | 4.374245 |
kable(aggregate( time~technique, data.long, mean ))
technique | time |
---|---|
Baseline | 6.414471 |
ForceEdge | 4.323404 |
kable(aggregate( time~technique+task, data.long, mean ))
technique | task | time |
---|---|---|
Baseline | Move | 8.226935 |
ForceEdge | Move | 4.500325 |
Baseline | Select | 4.602008 |
ForceEdge | Select | 4.146483 |
Post-hoc analysis using Bonferroni correction
attach(data.long)
pw <- pairwise.t.test(time, interaction(task,technique), paired = TRUE, p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
Move.Baseline | Select.Baseline | Move.ForceEdge | |
---|---|---|---|
Select.Baseline | 0 | NA | NA |
Move.ForceEdge | 0 | 1.0000000 | NA |
Select.ForceEdge | 0 | 0.0199735 | 0.1419558 |
For each task, post-hoc analysis showed significant differences (p < 0.003) between ForceEdge and Baseline. For select tasks, the average trial time was 4.1s with ForceEdge and 4.6s with Baseline. For move tasks, average trial time was 4.5s with ForceEdge and 8.2s with Baseline. As a result H1 is confirmed. Pairwise comparisons showed significant differences (p < 0.01) between the two techniques for each distance of the two tasks, except for the shortest distance and the Select task where ForceEdge and Baseline showed similar performance.