Loading and preparing data for analysis

data = read.table("XP1VisualFeedforward_logs.csv", header=TRUE, sep=",")

data = data %>% arrange(participantId, tech, block, targetSize, density)

# filtering first trial of each set, because we don't know where in the scene, the cursor come from.
data = data %>% filter(trialId > 1)

# aggregating by set of trials, and computing error rate:
dataErrorMeans = data %>%
    group_by(participantId, tech, block, targetSize, density) %>%
    summarize(errorRate = computeErrorRate(success))

# same aggregation as above, but we compute the mean time:
dataSuccessAggr = data %>%
    filter(success == "True") %>%
    group_by(participantId, tech, block, targetSize, density) %>%
    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", "tech", "block", "targetSize", "density"))

# useful if we exclude block 1 in some analysis:
dataAggrBlock23 = dataAggr %>% filter(block > 1)

techniques = unique(data$tech)
blocks = unique(data$block)
targetSizes = unique(data$targetSize)
densities = unique(data$density)

1 Selection time

1.1 Effect of blocks on selection time

1.1.1 Check the normality of data

data.long = melt(dataAggr, id = c("meanFinalTimer", "participantId", "tech", "block", "targetSize", "density"))

data.long$tech = factor(data.long$tech)
data.long$block = factor(data.long$block)
data.long$targetSize = factor(data.long$targetSize)
data.long$density = factor(data.long$density)

m <- aov(meanFinalTimer ~ tech*block*targetSize*density, data=data.long)
pander(normalCheck(m))

Shapiro-Wilk normality test

data: res W = 0.76689, p-value < 2.2e-16

Shapiro-Wilk normality test: res
Test statistic P value
0.7669 2.988e-33 * * *

Selection time does not follow a normal distribution.

1.1.2 Determine boxcox transform lambda to make residuals normal

boxcox(meanFinalTimer ~ tech*block*targetSize*density, data=data.long, plotit=T)

A lambda of around -1.2 is effective.

1.1.3 Transform data

datatr = data.long %>%
    mutate(meanFinalTimer = meanFinalTimer^(-1.2))
m <- aov(meanFinalTimer ~ tech*block, data=datatr)
pander(normalCheck(m))

Shapiro-Wilk normality test

data: res W = 0.99742, p-value = 0.1926

Shapiro-Wilk normality test: res
Test statistic P value
0.9974 0.1926

1.1.4 Repeated measures ANOVA on transformed data

anova = ezANOVA(datatr, dv=.(meanFinalTimer), wid=.(participantId), within=.(tech,block), detailed=TRUE)

# kable(anova$`Mauchly's Test for Sphericity`)
# kable(anova$`Sphericity Corrections`)
# kable(anova$ANOVA)
kable(anova_apa(anova, sph_corr ="gg", es = "ges", print=FALSE))
effect text
(Intercept) F(1, 11) = 304.16, p < .001, getasq = .95
tech F(5, 55) = 3.62, p = .007, getasq = .09
block F(1.16, 12.71) = 21.17, p < .001, getasq = .04
tech:block F(10, 110) = 1.58, p = .122, getasq < .01

1.1.5 Repeated measures ANOVA on non-transformed data

anova = ezANOVA(data.long, dv=.(meanFinalTimer), wid=.(participantId), within=.(tech,block), detailed=TRUE)

# kable(anova$`Mauchly's Test for Sphericity`)
# kable(anova$`Sphericity Corrections`)
# kable(anova$ANOVA)
kable(anova_apa(anova, sph_corr ="gg", es = "ges", print=FALSE))
effect text
(Intercept) F(1, 11) = 178.44, p < .001, getasq = .91
tech F(2.36, 25.93) = 2.87, p = .067, getasq = .06
block F(1.04, 11.42) = 12.27, p = .004, getasq = .04
tech:block F(2.44, 26.81) = 1.70, p = .197, getasq = .02

1.1.6 Post-hoc analysis with Bonferroni correction

attach(datatr)
pw <- pairwise.t.test(meanFinalTimer, interaction(block), p.adj = "bonferroni")
detach(datatr)
kable(pw$p.value)
1 2
2 0.0035985 NA
3 0.0000086 0.4320314

1.1.7 Mean time per block

kable(aggregate(meanFinalTimer~block, data.long, mean))
block meanFinalTimer
1 1.455466
2 1.290460
3 1.246896

There is learning between block 1 and blocks 2-3.

1.2 Analysis without first block

datatrBlock23 = dataAggrBlock23 %>%
    mutate(meanFinalTimer = meanFinalTimer^(-1.2))
m <- aov(meanFinalTimer ~ tech*block, data=datatrBlock23)
pander(normalCheck(m))

Shapiro-Wilk normality test

data: res W = 0.99675, p-value = 0.2995

Shapiro-Wilk normality test: res
Test statistic P value
0.9967 0.2995

1.2.1 Repeated measures ANOVA Mean time on transformed data

dataSuccesstr.long = melt(datatrBlock23, id = c("meanFinalTimer", "participantId", "tech", "block", "targetSize", "density"))

dataSuccesstr.long$tech = factor(dataSuccesstr.long$tech)
dataSuccesstr.long$block = factor(dataSuccesstr.long$block)
dataSuccesstr.long$targetSize = factor(dataSuccesstr.long$targetSize)
dataSuccesstr.long$density = factor(dataSuccesstr.long$density)

anova = ezANOVA(dataSuccesstr.long, dv=.(meanFinalTimer), wid=.(participantId), within=.(tech,targetSize,density), detailed=TRUE)

kable(anova_apa(anova, sph_corr ="gg", es = "ges", print=FALSE))
effect text
(Intercept) F(1, 11) = 306.85, p < .001, getasq = .95
tech F(5, 55) = 5.40, p < .001, getasq = .10
targetSize F(1, 11) = 108.34, p < .001, getasq = .07
density F(1, 11) = 176.26, p < .001, getasq = .11
tech:targetSize F(5, 55) = 28.14, p < .001, getasq = .05
tech:density F(5, 55) = 5.21, p < .001, getasq = .01
targetSize:density F(1, 11) = 1.02, p = .333, getasq < .01
tech:targetSize:density F(5, 55) = 2.47, p = .044, getasq < .01

1.2.2 Repeated measures ANOVA Mean time on non-transformed data

dataSuccess.long = melt(dataAggrBlock23, id = c("meanFinalTimer", "participantId", "tech", "block", "targetSize", "density"))

dataSuccess.long$tech = factor(dataSuccess.long$tech)
dataSuccess.long$block = factor(dataSuccess.long$block)
dataSuccess.long$targetSize = factor(dataSuccess.long$targetSize)
dataSuccess.long$density = factor(dataSuccess.long$density)

anova = ezANOVA(dataSuccess.long, dv=.(meanFinalTimer), wid=.(participantId), within=.(tech,targetSize,density), detailed=TRUE)

kable(anova_apa(anova, sph_corr ="gg", es = "ges", print=FALSE))
effect text
(Intercept) F(1, 11) = 221.05, p < .001, getasq = .93
tech F(2.15, 23.69) = 4.54, p = .019, getasq = .08
targetSize F(1, 11) = 74.63, p < .001, getasq = .05
density F(1, 11) = 67.97, p < .001, getasq = .07
tech:targetSize F(2.51, 27.58) = 22.65, p < .001, getasq = .04
tech:density F(2.42, 26.59) = 3.73, p = .030, getasq < .01
targetSize:density F(1, 11) = 3.08, p = .107, getasq < .01
tech:targetSize:density F(5, 55) = 1.81, p = .127, getasq < .01

1.2.3 Mean time per technique

tech meanFinalTimer
1_Raycasting 1.392760
2_Highlight 1.186913
3_3DBubble 1.415761
4_3DBubble_Highlight 1.218913
5_RopeCursor 1.226246
6_RopeCursor_Highlight 1.171475

1.2.3.1 Post-hoc analysis on technique with Bonferroni correction

attach(dataSuccesstr.long)
pw <- pairwise.t.test(meanFinalTimer, interaction(tech), p.adj = "bonferroni")
detach(dataSuccesstr.long)
kable(pw$p.value)
1_Raycasting 2_Highlight 3_3DBubble 4_3DBubble_Highlight 5_RopeCursor
2_Highlight 0.0000126 NA NA NA NA
3_3DBubble 1.0000000 0.0004345 NA NA NA
4_3DBubble_Highlight 0.0006327 1.0000000 0.0124187 NA NA
5_RopeCursor 0.0275991 0.9679974 0.2765704 1 NA
6_RopeCursor_Highlight 0.0000805 1.0000000 0.0021564 1 1

1.2.4 Mean time per size

kable(aggregate(meanFinalTimer~targetSize, dataSuccess.long, mean))
targetSize meanFinalTimer
Large 1.191243
Small 1.346113

1.2.5 Mean time per technique * size

tech targetSize meanFinalTimer
1_Raycasting Large 1.157715
2_Highlight Large 1.164152
3_3DBubble Large 1.350795
4_3DBubble_Highlight Large 1.162161
5_RopeCursor Large 1.173639
6_RopeCursor_Highlight Large 1.138997
1_Raycasting Small 1.627805
2_Highlight Small 1.209674
3_3DBubble Small 1.480727
4_3DBubble_Highlight Small 1.275666
5_RopeCursor Small 1.278852
6_RopeCursor_Highlight Small 1.203954

1.2.5.1 Post-hoc analysis with Bonferroni correction

attach(dataSuccesstr.long)
pw <- pairwise.t.test(meanFinalTimer, interaction(tech,targetSize), p.adj = "bonferroni")
detach(dataSuccesstr.long)
kable(pw$p.value)
1_Raycasting.Large 2_Highlight.Large 3_3DBubble.Large 4_3DBubble_Highlight.Large 5_RopeCursor.Large 6_RopeCursor_Highlight.Large 1_Raycasting.Small 2_Highlight.Small 3_3DBubble.Small 4_3DBubble_Highlight.Small 5_RopeCursor.Small
2_Highlight.Large 1.0000000 NA NA NA NA NA NA NA NA NA NA
3_3DBubble.Large 1.0000000 0.1156196 NA NA NA NA NA NA NA NA NA
4_3DBubble_Highlight.Large 1.0000000 1.0000000 0.3384789 NA NA NA NA NA NA NA NA
5_RopeCursor.Large 1.0000000 1.0000000 1.0000000 1.0000000 NA NA NA NA NA NA NA
6_RopeCursor_Highlight.Large 1.0000000 1.0000000 0.5271546 1.0000000 1.000000 NA NA NA NA NA NA
1_Raycasting.Small 0.0000000 0.0000000 0.0004667 0.0000000 0.000000 0.0000000 NA NA NA NA NA
2_Highlight.Small 1.0000000 1.0000000 1.0000000 1.0000000 1.000000 1.0000000 0.0000000 NA NA NA NA
3_3DBubble.Small 0.0469243 0.0006580 1.0000000 0.0028302 0.058153 0.0052268 0.0894362 0.1465345 NA NA NA
4_3DBubble_Highlight.Small 1.0000000 1.0000000 1.0000000 1.0000000 1.000000 1.0000000 0.0000077 1.0000000 1.0000000 NA NA
5_RopeCursor.Small 1.0000000 0.1846784 1.0000000 0.5184801 1.000000 0.7927265 0.0002417 1.0000000 1.0000000 1 NA
6_RopeCursor_Highlight.Small 1.0000000 1.0000000 1.0000000 1.0000000 1.000000 1.0000000 0.0000001 1.0000000 0.1964209 1 1

1.2.6 Mean time per technique * density

tech density meanFinalTimer
1_Raycasting High 1.423595
2_Highlight High 1.273392
3_3DBubble High 1.535603
4_3DBubble_Highlight High 1.306500
5_RopeCursor High 1.341534
6_RopeCursor_Highlight High 1.270674
1_Raycasting Low 1.361924
2_Highlight Low 1.100434
3_3DBubble Low 1.295919
4_3DBubble_Highlight Low 1.131327
5_RopeCursor Low 1.110958
6_RopeCursor_Highlight Low 1.072277

1.2.6.1 Post-hoc analysis with Bonferroni correction

attach(dataSuccesstr.long)
pw <- pairwise.t.test(meanFinalTimer, interaction(tech,density), p.adj = "bonferroni")
detach(dataSuccesstr.long)
kable(pw$p.value)
1_Raycasting.High 2_Highlight.High 3_3DBubble.High 4_3DBubble_Highlight.High 5_RopeCursor.High 6_RopeCursor_Highlight.High 1_Raycasting.Low 2_Highlight.Low 3_3DBubble.Low 4_3DBubble_Highlight.Low 5_RopeCursor.Low
2_Highlight.High 0.7066065 NA NA NA NA NA NA NA NA NA NA
3_3DBubble.High 1.0000000 0.2036162 NA NA NA NA NA NA NA NA NA
4_3DBubble_Highlight.High 1.0000000 1.0000000 1.0000000 NA NA NA NA NA NA NA NA
5_RopeCursor.High 1.0000000 1.0000000 1.0000000 1.0000000 NA NA NA NA NA NA NA
6_RopeCursor_Highlight.High 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 NA NA NA NA NA NA
1_Raycasting.Low 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 NA NA NA NA NA
2_Highlight.Low 0.0000008 0.0866752 0.0000001 0.0085781 0.0000602 0.0067164 0.0001203 NA NA NA NA
3_3DBubble.Low 0.8064324 1.0000000 0.2363499 1.0000000 1.0000000 1.0000000 1.0000000 0.0737407 NA NA NA
4_3DBubble_Highlight.Low 0.0000241 0.6554661 0.0000028 0.0922959 0.0012035 0.0747950 0.0022245 1.0000000 0.5726057 NA NA
5_RopeCursor.Low 0.0001475 1.0000000 0.0000192 0.3049330 0.0056859 0.2520412 0.0100441 1.0000000 1.0000000 1 NA
6_RopeCursor_Highlight.Low 0.0000004 0.0591247 0.0000000 0.0055100 0.0000348 0.0042890 0.0000705 1.0000000 0.0500744 1 1

2 Error rate

2.1 Effect of blocks on error rate

2.1.1 Check the normality of data

data.long = melt(dataAggr, id = c("errorRate", "participantId", "tech", "block", "targetSize", "density"))

data.long$tech = factor(data.long$tech)
data.long$block = factor(data.long$block)
data.long$targetSize = factor(data.long$targetSize)
data.long$density = factor(data.long$density)
m <- aov(errorRate ~ tech*block*targetSize*density, data=data.long)
pander(normalCheck(m))

Shapiro-Wilk normality test

data: res W = 0.86954, p-value < 2.2e-16

Shapiro-Wilk normality test: res
Test statistic P value
0.8695 3.206e-26 * * *

Error rate does not follow a normal distribution.

2.1.2 Effect of block on error rate

m = art(errorRate ~ block + (1|participantId), data=data.long)
kable(anova(m)) 
Term F Df Df.res Pr(>F)
block block 1.626588 2 850 0.1972106

No learning or fatigue effect.

2.1.3 Running ANOVA on ART

m = art(errorRate ~ tech*targetSize*density + (1|participantId), data=data.long)
kable(anova(m)) 
Term F Df Df.res Pr(>F)
tech tech 30.330368 5 829 0.0000000
targetSize targetSize 140.672278 1 829 0.0000000
density density 6.596702 1 829 0.0103908
tech:targetSize tech:targetSize 26.400011 5 829 0.0000000
tech:density tech:density 4.664141 5 829 0.0003316
targetSize:density targetSize:density 1.487203 1 829 0.2229978
tech:targetSize:density tech:targetSize:density 3.991382 5 829 0.0013885

2.1.4 Repeated measures ANOVA on non-transformed data

anova = ezANOVA(data.long, dv=.(errorRate), wid=.(participantId), within=.(tech,block,targetSize,density), detailed=TRUE)

kable(anova_apa(anova, sph_corr ="gg", es = "ges", print=FALSE))
effect text
(Intercept) F(1, 11) = 67.75, p < .001, getasq = .31
tech F(1.97, 21.62) = 15.55, p < .001, getasq = .22
block F(2, 22) = 1.05, p = .368, getasq < .01
targetSize F(1, 11) = 28.87, p < .001, getasq = .05
density F(1, 11) = 3.48, p = .089, getasq < .01
tech:block F(4.30, 47.28) = 0.83, p = .517, getasq = .01
tech:targetSize F(1.78, 19.58) = 21.29, p < .001, getasq = .12
block:targetSize F(2, 22) = 3.00, p = .070, getasq < .01
tech:density F(5, 55) = 5.48, p < .001, getasq = .02
block:density F(2, 22) = 0.19, p = .831, getasq < .01
targetSize:density F(1, 11) = 1.06, p = .325, getasq < .01
tech:block:targetSize F(10, 110) = 4.28, p < .001, getasq = .03
tech:block:density F(10, 110) = 1.44, p = .172, getasq = .01
tech:targetSize:density F(5, 55) = 1.42, p = .233, getasq < .01
block:targetSize:density F(2, 22) = 0.88, p = .427, getasq < .01
tech:block:targetSize:density F(3.25, 35.80) = 1.71, p = .179, getasq = .02

2.1.5 Overall error rate

kable(data.long %>% summarise(mean = mean(errorRate)))
mean
4.74537

2.1.6 Error rate per technique

tech errorRate
1_Raycasting 12.885803
2_Highlight 2.237654
3_3DBubble 3.780864
4_3DBubble_Highlight 1.929012
5_RopeCursor 4.320988
6_RopeCursor_Highlight 3.317901

2.1.6.1 Post-hoc analysis technique and size

pw = lsmeans(artlm(m, "tech"), pairwise ~ tech, adjust = "bonferroni")
## Loading required namespace: lmerTest
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
contrast estimate SE df t.ratio p.value
1_Raycasting - 2_Highlight 253.79514 25.22081 51.8125000 10.0629251 0.0000000
1_Raycasting - 3_3DBubble 219.44444 25.22081 51.8125000 8.7009271 0.0000000
1_Raycasting - 4_3DBubble_Highlight 265.13542 25.22081 51.8125000 10.5125648 0.0000000
1_Raycasting - 5_RopeCursor 185.79167 25.22081 51.8125000 7.3666014 0.0000000
1_Raycasting - 6_RopeCursor_Highlight 229.54167 25.22081 0.1070506 9.1012799 1.0000000
2_Highlight - 3_3DBubble -34.35069 25.22081 51.8125000 -1.3619980 1.0000000
2_Highlight - 4_3DBubble_Highlight 11.34028 25.22081 51.8125000 0.4496397 1.0000000
2_Highlight - 5_RopeCursor -68.00347 25.22081 51.8125000 -2.6963237 0.1415166
2_Highlight - 6_RopeCursor_Highlight -24.25347 25.22081 0.1070506 -0.9616452 1.0000000
3_3DBubble - 4_3DBubble_Highlight 45.69097 25.22081 51.8125000 1.8116377 1.0000000
3_3DBubble - 5_RopeCursor -33.65278 25.22081 51.8125000 -1.3343257 1.0000000
3_3DBubble - 6_RopeCursor_Highlight 10.09722 25.22081 0.1070506 0.4003528 1.0000000
4_3DBubble_Highlight - 5_RopeCursor -79.34375 25.22081 51.8125000 -3.1459634 0.0411329
4_3DBubble_Highlight - 6_RopeCursor_Highlight -35.59375 25.22081 0.1070506 -1.4112849 1.0000000
5_RopeCursor - 6_RopeCursor_Highlight 43.75000 25.22081 0.1070506 1.7346785 1.0000000
attach(data.long)
pw <- pairwise.t.test(errorRate, interaction(tech), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
1_Raycasting 2_Highlight 3_3DBubble 4_3DBubble_Highlight 5_RopeCursor
2_Highlight 0 NA NA NA NA
3_3DBubble 0 1.0000000 NA NA NA
4_3DBubble_Highlight 0 1.0000000 0.8136096 NA NA
5_RopeCursor 0 0.4559261 1.0000000 0.1945717 NA
6_RopeCursor_Highlight 0 1.0000000 1.0000000 1.0000000 1

2.1.7 Error rate per technique * size

tech targetSize errorRate
1_Raycasting Large 5.555556
2_Highlight Large 2.623457
3_3DBubble Large 3.240741
4_3DBubble_Highlight Large 1.543210
5_RopeCursor Large 3.703704
6_RopeCursor_Highlight Large 2.469136
1_Raycasting Small 20.216049
2_Highlight Small 1.851852
3_3DBubble Small 4.320988
4_3DBubble_Highlight Small 2.314815
5_RopeCursor Small 4.938272
6_RopeCursor_Highlight Small 4.166667

2.1.7.1 Post-hoc analysis with Bonferroni correction for target size

datafilt.long = data.long %>% filter(targetSize == "Small")
m = art(errorRate ~ tech*density + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "tech"), pairwise ~ tech, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
contrast estimate SE df t.ratio p.value
1_Raycasting - 2_Highlight 168.000000 16.69969 102.2500000 10.0600667 0.0000000
1_Raycasting - 3_3DBubble 124.638889 16.69969 102.2500000 7.4635449 0.0000000
1_Raycasting - 4_3DBubble_Highlight 162.027778 16.69969 102.2500000 9.7024420 0.0000000
1_Raycasting - 5_RopeCursor 123.638889 16.69969 102.2500000 7.4036635 0.0000000
1_Raycasting - 6_RopeCursor_Highlight 132.361111 16.69969 0.2112603 7.9259620 1.0000000
2_Highlight - 3_3DBubble -43.361111 16.69969 102.2500000 -2.5965218 0.1620584
2_Highlight - 4_3DBubble_Highlight -5.972222 16.69969 102.2500000 -0.3576247 1.0000000
2_Highlight - 5_RopeCursor -44.361111 16.69969 102.2500000 -2.6564032 0.1374633
2_Highlight - 6_RopeCursor_Highlight -35.638889 16.69969 0.2112603 -2.1341048 1.0000000
3_3DBubble - 4_3DBubble_Highlight 37.388889 16.69969 102.2500000 2.2388971 0.4099389
3_3DBubble - 5_RopeCursor -1.000000 16.69969 102.2500000 -0.0598813 1.0000000
3_3DBubble - 6_RopeCursor_Highlight 7.722222 16.69969 0.2112603 0.4624171 1.0000000
4_3DBubble_Highlight - 5_RopeCursor -38.388889 16.69969 102.2500000 -2.2987785 0.3532782
4_3DBubble_Highlight - 6_RopeCursor_Highlight -29.666667 16.69969 0.2112603 -1.7764800 1.0000000
5_RopeCursor - 6_RopeCursor_Highlight 8.722222 16.69969 0.2112603 0.5222984 1.0000000
datafilt.long = data.long %>% filter(targetSize == "Large")
m = art(errorRate ~ tech*density + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "tech"), pairwise ~ tech, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
contrast estimate SE df t.ratio p.value
1_Raycasting - 2_Highlight 42.7638889 17.86339 102.2499997 2.3939409 0.2773638
1_Raycasting - 3_3DBubble 15.7500000 17.86339 102.2499997 0.8816918 1.0000000
1_Raycasting - 4_3DBubble_Highlight 56.5763889 17.86339 102.2499997 3.1671706 0.0304434
1_Raycasting - 5_RopeCursor 28.7916667 17.86339 102.2499997 1.6117699 1.0000000
1_Raycasting - 6_RopeCursor_Highlight 42.3680556 17.86339 0.2112603 2.3717820 1.0000000
2_Highlight - 3_3DBubble -27.0138889 17.86339 102.2499997 -1.5122491 1.0000000
2_Highlight - 4_3DBubble_Highlight 13.8125000 17.86339 102.2499997 0.7732297 1.0000000
2_Highlight - 5_RopeCursor -13.9722222 17.86339 102.2499997 -0.7821710 1.0000000
2_Highlight - 6_RopeCursor_Highlight -0.3958333 17.86339 0.2112603 -0.0221589 1.0000000
3_3DBubble - 4_3DBubble_Highlight 40.8263889 17.86339 102.2499997 2.2854788 0.3652298
3_3DBubble - 5_RopeCursor 13.0416667 17.86339 102.2499997 0.7300781 1.0000000
3_3DBubble - 6_RopeCursor_Highlight 26.6180556 17.86339 0.2112603 1.4900902 1.0000000
4_3DBubble_Highlight - 5_RopeCursor -27.7847222 17.86339 102.2499997 -1.5554007 1.0000000
4_3DBubble_Highlight - 6_RopeCursor_Highlight -14.2083333 17.86339 0.2112603 -0.7953886 1.0000000
5_RopeCursor - 6_RopeCursor_Highlight 13.5763889 17.86339 0.2112603 0.7600121 1.0000000
attach(data.long)
pw <- pairwise.t.test(errorRate, interaction(tech,targetSize), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
1_Raycasting.Large 2_Highlight.Large 3_3DBubble.Large 4_3DBubble_Highlight.Large 5_RopeCursor.Large 6_RopeCursor_Highlight.Large 1_Raycasting.Small 2_Highlight.Small 3_3DBubble.Small 4_3DBubble_Highlight.Small 5_RopeCursor.Small
2_Highlight.Large 1.0000000 NA NA NA NA NA NA NA NA NA NA
3_3DBubble.Large 1.0000000 1 NA NA NA NA NA NA NA NA NA
4_3DBubble_Highlight.Large 0.1030623 1 1 NA NA NA NA NA NA NA NA
5_RopeCursor.Large 1.0000000 1 1 1.0000000 NA NA NA NA NA NA NA
6_RopeCursor_Highlight.Large 0.9801809 1 1 1.0000000 1 NA NA NA NA NA NA
1_Raycasting.Small 0.0000000 0 0 0.0000000 0 0 NA NA NA NA NA
2_Highlight.Small 0.2303157 1 1 1.0000000 1 1 0 NA NA NA NA
3_3DBubble.Small 1.0000000 1 1 1.0000000 1 1 0 1.0000000 NA NA NA
4_3DBubble_Highlight.Small 0.6961607 1 1 1.0000000 1 1 0 1.0000000 1 NA NA
5_RopeCursor.Small 1.0000000 1 1 0.4879303 1 1 0 0.9801809 1 1 NA
6_RopeCursor_Highlight.Small 1.0000000 1 1 1.0000000 1 1 0 1.0000000 1 1 1

2.1.8 Error rate per technique * density

tech density errorRate
1_Raycasting High 11.265432
2_Highlight High 2.469136
3_3DBubble High 6.018518
4_3DBubble_Highlight High 2.469136
5_RopeCursor High 5.092593
6_RopeCursor_Highlight High 3.858025
1_Raycasting Low 14.506173
2_Highlight Low 2.006173
3_3DBubble Low 1.543210
4_3DBubble_Highlight Low 1.388889
5_RopeCursor Low 3.549383
6_RopeCursor_Highlight Low 2.777778

2.1.8.1 Post-hoc analysis with Bonferroni correction

datafilt.long = data.long %>% filter(density == "Low")
m = art(errorRate ~ tech*targetSize + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "tech"), pairwise ~ tech, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
contrast estimate SE df t.ratio p.value
1_Raycasting - 2_Highlight 144.222222 16.56432 102.2500000 8.7067990 0.000000
1_Raycasting - 3_3DBubble 148.930556 16.56432 102.2500000 8.9910445 0.000000
1_Raycasting - 4_3DBubble_Highlight 162.708333 16.56432 102.2500000 9.8228188 0.000000
1_Raycasting - 5_RopeCursor 127.375000 16.56432 102.2500000 7.6897201 0.000000
1_Raycasting - 6_RopeCursor_Highlight 120.013889 16.56432 0.2112603 7.2453246 1.000000
2_Highlight - 3_3DBubble 4.708333 16.56432 102.2500001 0.2842455 1.000000
2_Highlight - 4_3DBubble_Highlight 18.486111 16.56432 102.2500001 1.1160198 1.000000
2_Highlight - 5_RopeCursor -16.847222 16.56432 102.2500000 -1.0170789 1.000000
2_Highlight - 6_RopeCursor_Highlight -24.208333 16.56432 0.2112603 -1.4614745 1.000000
3_3DBubble - 4_3DBubble_Highlight 13.777778 16.56432 102.2500000 0.8317743 1.000000
3_3DBubble - 5_RopeCursor -21.555556 16.56432 102.2500001 -1.3013244 1.000000
3_3DBubble - 6_RopeCursor_Highlight -28.916667 16.56432 0.2112603 -1.7457199 1.000000
4_3DBubble_Highlight - 5_RopeCursor -35.333333 16.56432 102.2500001 -2.1330987 0.529644
4_3DBubble_Highlight - 6_RopeCursor_Highlight -42.694444 16.56432 0.2112603 -2.5774942 1.000000
5_RopeCursor - 6_RopeCursor_Highlight -7.361111 16.56432 0.2112603 -0.4443956 1.000000
datafilt.long = data.long %>% filter(density == "High")
m = art(errorRate ~ tech*targetSize + (1|participantId), data=datafilt.long)
pw = lsmeans(artlm(m, "tech"), pairwise ~ tech, adjust = "bonferroni")
## NOTE: Results may be misleading due to involvement in interactions
kable(summary(pw$contrasts))
contrast estimate SE df t.ratio p.value
1_Raycasting - 2_Highlight 114.94444 17.64166 102.2500000 6.5155115 0.0000000
1_Raycasting - 3_3DBubble 67.66667 17.64166 102.2500000 3.8356177 0.0032531
1_Raycasting - 4_3DBubble_Highlight 113.81944 17.64166 102.2500000 6.4517420 0.0000001
1_Raycasting - 5_RopeCursor 74.29167 17.64166 102.2500000 4.2111492 0.0008218
1_Raycasting - 6_RopeCursor_Highlight 92.19444 17.64166 0.2112603 5.2259504 1.0000000
2_Highlight - 3_3DBubble -47.27778 17.64166 102.2500000 -2.6798938 0.1287763
2_Highlight - 4_3DBubble_Highlight -1.12500 17.64166 102.2500000 -0.0637695 1.0000000
2_Highlight - 5_RopeCursor -40.65278 17.64166 102.2500000 -2.3043623 0.3483639
2_Highlight - 6_RopeCursor_Highlight -22.75000 17.64166 0.2112603 -1.2895611 1.0000000
3_3DBubble - 4_3DBubble_Highlight 46.15278 17.64166 102.2500000 2.6161243 0.1536014
3_3DBubble - 5_RopeCursor 6.62500 17.64166 102.2500000 0.3755315 1.0000000
3_3DBubble - 6_RopeCursor_Highlight 24.52778 17.64166 0.2112603 1.3903327 1.0000000
4_3DBubble_Highlight - 5_RopeCursor -39.52778 17.64166 102.2500000 -2.2405928 0.4082309
4_3DBubble_Highlight - 6_RopeCursor_Highlight -21.62500 17.64166 0.2112603 -1.2257916 1.0000000
5_RopeCursor - 6_RopeCursor_Highlight 17.90278 17.64166 0.2112603 1.0148012 1.0000000
attach(data.long)
pw <- pairwise.t.test(errorRate, interaction(tech,density), p.adj = "bonferroni")
detach(data.long)
kable(pw$p.value)
1_Raycasting.High 2_Highlight.High 3_3DBubble.High 4_3DBubble_Highlight.High 5_RopeCursor.High 6_RopeCursor_Highlight.High 1_Raycasting.Low 2_Highlight.Low 3_3DBubble.Low 4_3DBubble_Highlight.Low 5_RopeCursor.Low
2_Highlight.High 0.0000000 NA NA NA NA NA NA NA NA NA NA
3_3DBubble.High 0.0070717 0.5689067 NA NA NA NA NA NA NA NA NA
4_3DBubble_Highlight.High 0.0000000 1.0000000 0.5689067 NA NA NA NA NA NA NA NA
5_RopeCursor.High 0.0003544 1.0000000 1.0000000 1 NA NA NA NA NA NA NA
6_RopeCursor_Highlight.High 0.0000034 1.0000000 1.0000000 1 1.0000000 NA NA NA NA NA NA
1_Raycasting.Low 1.0000000 0.0000000 0.0000000 0 0.0000000 0 NA NA NA NA NA
2_Highlight.Low 0.0000000 1.0000000 0.1980023 1 1.0000000 1 0 NA NA NA NA
3_3DBubble.Low 0.0000000 1.0000000 0.0619977 1 0.5689067 1 0 1 NA NA NA
4_3DBubble_Highlight.Low 0.0000000 1.0000000 0.0411192 1 0.4048918 1 0 1 1 NA NA
5_RopeCursor.Low 0.0000010 1.0000000 1.0000000 1 1.0000000 1 0 1 1 1 NA
6_RopeCursor_Highlight.Low 0.0000000 1.0000000 1.0000000 1 1.0000000 1 0 1 1 1 1

3 Preferences

techniques count
1_Raycasting 1
2_Highlight 3
3_3DBubble 0
4_3DBubble_Highlight 3
5_RopeCursor 1
6_RopeCursor_Highlight 4