-
Notifications
You must be signed in to change notification settings - Fork 0
/
analysis.Rmd
423 lines (325 loc) · 15.3 KB
/
analysis.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
---
title: "Responses to Virtual Environments - Preliminary Analysis"
author: Tiernan J. Cahill
output: html_notebook
---
```{r setup, include=FALSE}
library(dplyr)
library(knitr)
library(ggplot2)
library(rstatix)
library(ggpubr)
library(rcompanion)
study_data <- readRDS("data/congruity_data.rds")
```
> **AUTHOR'S NOTE**: This notebook was originally prepared based on results derived from the unweighted calculation of SSQ. Consequently, not all commentary may apply to computed results at present.
# Diagnostics
Before we beginning our analysis, we check to see if the measured variables of interest are nearly-normally distributed, so we can make decisions about what sort of models will be appropriate. We can begin with a quick visual inspection using histograms.
```{r diag}
# ITQ (Control variable)
ggplot(study_data, aes(x = ITQ)) +
geom_histogram(binwidth = 5, fill = "#0AA57F", alpha = 0.8) +
labs(x="Immersive Tendencies", y = "Count")
# Spatal presence (Resposne variable)
ggplot(study_data, aes(x = SPQ)) +
geom_histogram(binwidth = 0.5, fill = "skyblue", alpha = 0.8) +
facet_grid(rows = vars(condition)) +
labs(x = "Spatial Presence", y = "Count")
# Spatial situation (Response variable)
ggplot(study_data, aes(x = SSM)) +
geom_histogram(binwidth = 0.5, fill = "#5964B3", alpha = 0.8) +
facet_grid(rows = vars(condition)) +
labs(x = "Spatial Situation", y = "Count")
# Self-presence (Response variable)
ggplot(study_data, aes(x = SPSL)) +
geom_histogram(binwidth = 0.5, fill = "#3439C8", alpha = 0.8) +
facet_grid(rows = vars(condition)) +
labs(x="Self-Presence", y = "Count")
# Suspension of disbelief (Response variable)
ggplot(study_data, aes(x = SoD)) +
geom_histogram(binwidth = 0.5, fill = "#004DC3", alpha = 0.8)+
facet_grid(rows = vars(condition)) +
labs(x="Suspension of Disbelief", y = "Count")
# Simulator sickness (Response variable)
ggplot(study_data, aes(x = sim_sick)) +
geom_histogram(binwidth = 5, fill = "#490415", alpha = 0.8) +
labs(x="Simulator Sickness", y = "Count")
```
From the visualization, it appears that most of the variables of interest allow us the assumption of near-normality, with the exception of simulator sickness, which is skewed left (since many more participants experience a few minor symptoms than many major symptoms). We will deal with this later. We can confirm this with a Shapiro-Wilk test.
```{r sw-test, warning=FALSE}
shapiro.test(study_data$sim_sick)
```
# Hypothesis Tests
## Presence
We are interested in whether measures of presence vary significantly between control and breach conditions in each of the three experiments. This is a one-sided test, since we can reasonably hypothesize that presence will be lower in the breach condition.
### Covariates
Establish, firstly, that there is a correlation between ITQ and SPQ, indicating that this is a relavent control variable.
```{r cor-test}
cor.test(study_data$ITQ, y = study_data$SPQ, alternative = "greater", method = "pearson")
```
### Overall Breaching Effects
```{r presence-viz}
study_data %>%
ggplot(aes(x = control, y = SPQ)) +
geom_violin(fill = "lightgreen", alpha = 0.8) +
xlab("Condition") + ylab("Spatial Presence") +
stat_summary(fun.y=mean, geom="point", shape=23, size=2)
```
```{r presence-test}
bartlett.test(SPQ ~ control, study_data)
t.test(SPQ ~ control, study_data, alternative = "greater", var.equal = T)
study_data %>%
anova_test(SPQ ~ ITQ + control , type = 2, effect.size = "ges", observed = "ITQ")
```
For the sake of simplicity, it's worth looking at an aggregate measure of spatial presence.
Let's see how this measure stacks up, visually, in the different breaching experiments.
```{r spq-viz}
sensory.plot <- study_data %>%
filter(condition == "SENSORY") %>%
ggplot(aes(x = control, y = SPQ)) +
geom_boxplot(fill = "#E69F00", alpha = 0.8) +
ylim(1,5) +
labs(title="Sensory", x = "Condition", y = "Spatial Presence")
enviro.plot <- study_data %>%
filter(condition == "ENVIRONMENTAL") %>%
ggplot(aes(x = control, y = SPQ)) +
geom_boxplot(fill = "#56B4E9", alpha = 0.8) +
ylim(1,5) +
labs(title="Environmental", x = "Condition", y = "Spatial Presence")
thematic.plot <- study_data %>%
filter(condition == "THEMATIC") %>%
ggplot(aes(x = control, y = SPQ)) +
geom_boxplot(fill = "#009E73", alpha = 0.8) +
ylim(1,5) +
labs(title="Thematic", x = "Condition", y = "Spatial Presence")
ggarrange(sensory.plot, enviro.plot, thematic.plot,
# labels = c("Sensory", "Environmental", "Thematic"),
ncol = 3)
```
<!-- This looks like it might give us a clearer picture of the differences between the conditions; however, it also appears that there may be some outliers in the data. Let's first remove those. -->
<!-- ```{r spq-clean} -->
<!-- study_data.rm_out <- study_data %>% -->
<!-- filter(SPQ < median(study_data$SPQ, na.rm=T) + -->
<!-- 2*IQR(study_data$SPQ, na.rm=T)) %>% -->
<!-- filter(SPQ > median(study_data$SPQ, na.rm=T) - -->
<!-- 2*IQR(study_data$SPQ, na.rm=T)) -->
<!-- sensory_data.rm_out <- study_data.rm_out %>% -->
<!-- filter(condition == "SENSORY") -->
<!-- enviro_data.rm_out <- study_data.rm_out %>% -->
<!-- filter(condition == "ENVIRONMENTAL") -->
<!-- thematic_data.rm_out <- study_data.rm_out %>% -->
<!-- filter(condition == "THEMATIC") -->
<!-- ``` -->
Let's try running some tests.
```{r spq-tests}
sensory_data <- study_data %>%
filter(condition == "SENSORY")
enviro_data <- study_data %>%
filter(condition == "ENVIRONMENTAL")
thematic_data <- study_data %>%
filter(condition == "THEMATIC")
# Sensory breach
bartlett.test(SPQ ~ control, sensory_data)
t.test(SPQ ~ control, sensory_data, alternative = "greater", var.equal = TRUE)
# Environmental breach
bartlett.test(SPQ ~ control, enviro_data)
t.test(SPQ ~ control, enviro_data, alternative = "greater", var.equal = TRUE)
# Thematic breach
bartlett.test(SPQ ~ control, thematic_data)
t.test(SPQ ~ control, thematic_data, alternative = "greater", var.equal = TRUE)
```
This seems to indicate that the differences in overall spatial presence are negligible for the spatial and environmental breaches, but quite significant for the thematic breach. Let's examine this again, controlling for individual differences in immersive tendencies.
```{r spq-tests-control}
sensory_data %>%
anova_test(SPQ ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
enviro_data %>%
anova_test(SPQ ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
thematic_data %>%
anova_test(SPQ ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
```
The results from the previous tests are mirrored here.
### Sensory Congruity
First, looking at the experiment in which sensory congruity was breached, we can visualize the presence measures reported by the two groups (in the control and breach conditions).
```{r sensory-viz}
# Spatial situation
sensory_data %>%
ggplot(aes(x = control, y = SSM)) +
geom_boxplot(fill = "#5964B3", alpha = 0.8) +
xlab("Condition") + ylab("Spatial Situation")
# Self-presence / Self-location
sensory_data %>%
ggplot(aes(x = control, y = SPSL)) +
geom_boxplot(fill = "#3439C8", alpha = 0.8) +
xlab("Condition") + ylab("Self-Presence / Self-Location")
# Suspension of disbelief
sensory_data %>%
ggplot(aes(x = control, y = SoD)) +
geom_boxplot(fill = "#004DC3", alpha = 0.8) +
xlab("Condition") + ylab("Suspension of Disbelief")
```
Next, we can run some statistical tests, starting with simple t-tests.
```{r sensory-tests}
bartlett.test(SSM ~ control, sensory_data)
t.test(SSM ~ control, sensory_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SPSL ~ control, sensory_data)
t.test(SPSL ~ control, sensory_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SoD ~ control, sensory_data)
t.test(SoD ~ control, sensory_data, alternative = "greater", var.equal = TRUE)
```
It looks like we can assume equal variances based on the results of Bartlett's tests, but that the differences between groups aren't significant. Let's try again, controlling for individual differences in immersive tendencies using an ANCOVA.
```{r sensory-tests-control}
sensory_data %>%
anova_test(SSM ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
sensory_data %>%
anova_test(SPSL ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
sensory_data %>%
anova_test(SoD ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
```
It still doesn't look like there's much of a significant difference between the experimental groups when controlling for immersive tendencies.
### Environment Congruity
We repeat the above procedure for the second experiment, where environmental congruity was breached.
```{r enviro-viz, warnings = FALSE}
# Spatial situation
enviro_data %>%
ggplot(aes(x = control, y = SSM)) +
geom_boxplot(fill = "#5964B3", alpha = 0.8) +
xlab("Condition") + ylab("Spatial Situation")
# Self-presence / Self-location
enviro_data %>%
ggplot(aes(x = control, y = SPSL)) +
geom_boxplot(fill = "#3439C8", alpha = 0.8) +
xlab("Condition") + ylab("Self-Presence / Self-Location")
# Suspension of disbelief
enviro_data %>%
ggplot(aes(x = control, y = SoD)) +
geom_boxplot(fill = "#004DC3", alpha = 0.8) +
xlab("Condition") + ylab("Suspension of Disbelief")
```
```{r enviro-tests}
bartlett.test(SSM ~ control, enviro_data)
t.test(SSM ~ control, enviro_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SPSL ~ control, enviro_data)
t.test(SPSL ~ control, enviro_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SoD ~ control, enviro_data)
t.test(SoD ~ control, enviro_data, alternative = "greater", var.equal = TRUE)
```
It looks like there might be a significant difference in suspension of disbelief, based on the T test. Let's see what happens when we control for immersive tendencies.
```{r enviro-tests-control}
enviro_data %>%
anova_test(SSM ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
enviro_data %>%
anova_test(SPSL ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
enviro_data %>%
anova_test(SoD ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
```
In this case, because the test is one-sided, a p-value < 0.1 is considered significant, which remains the case for Suspension of Disbelief in the environmnental breach condition, even when controlling for immersive tendencies.
### Thematic
Finally, let's repeat all of the above steps for the thematic breach condition.
```{r thematic-viz, warnings = FALSE}
# Spatial situation
thematic_data %>%
ggplot(aes(x = control, y = SSM)) +
geom_boxplot(fill = "#5964B3", alpha = 0.8) +
xlab("Condition") + ylab("Spatial Situation")
# Self-presence / Self-location
thematic_data %>%
ggplot(aes(x = control, y = SPSL)) +
geom_boxplot(fill = "#3439C8", alpha = 0.8) +
xlab("Condition") + ylab("Self-Presence / Self-Location")
# Suspension of disbelief
thematic_data %>%
ggplot(aes(x = control, y = SoD)) +
geom_boxplot(fill = "#004DC3", alpha = 0.8) +
xlab("Condition") + ylab("Suspension of Disbelief")
```
```{r thematic-tests}
bartlett.test(SSM ~ control, thematic_data)
t.test(SSM ~ control, thematic_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SPSL ~ control, thematic_data)
t.test(SPSL ~ control, thematic_data, alternative = "greater", var.equal = TRUE)
bartlett.test(SoD ~ control, thematic_data)
t.test(SoD ~ control, thematic_data, alternative = "greater", var.equal = TRUE)
```
It appears that self-presence / self-location is significantly lower in the thematic breach condition. Let's now control for immersive tendencies, as before.
```{r thematic-tests-control}
thematic_data %>%
anova_test(SSM ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
thematic_data %>%
anova_test(SPSL ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
thematic_data %>%
anova_test(SoD ~ ITQ + control, type = 2, effect.size = "ges", observed = "ITQ")
```
The previous findings are mirrored in the ANCOVA test.
## Simulator Sickness
We are also interested in whether simulator sickness varies significantly between breaching and control conditions. Because the data is so heavily skewed left, we will begin by performing a log transform.
```{r ss-clean}
ggplot(study_data, aes(x = sim_sick)) +
geom_histogram(binwidth = 20, fill = "#490415", alpha = 0.8) +
labs(x = "Simulator Sickness", y = "Frequency")
study_data <- study_data %>%
mutate(sim_sick.log = log10(sim_sick+1)) # This is necessary because of the possibility of a 0 value
# Simulator sickness (Response variable)
ggplot(study_data, aes(x = sim_sick.log)) +
geom_histogram(binwidth = 0.25, fill = "#490415", alpha = 0.8) +
labs(x="Simulator Sickness [Log-Transformed]", y = "Count")
shapiro.test(study_data$sim_sick.log)
```
```{r ss-viz}
sensory.ss.plot <- study_data %>%
filter(condition == "SENSORY") %>%
ggplot(aes(x = control, y = sim_sick.log)) +
ylim(0, 4) +
geom_boxplot(fill = "#E69F00", alpha = 0.8) +
labs(title="Sensory", x = "Condition", y = "Simulator Sickness")
enviro.ss.plot <- study_data %>%
filter(condition == "ENVIRONMENTAL") %>%
ggplot(aes(x = control, y = sim_sick.log)) +
ylim(0, 4) +
geom_boxplot(fill = "#56B4E9", alpha = 0.8) +
labs(title="Environmental", x = "Condition", y = "Simulator Sickness")
thematic.ss.plot <- study_data %>%
filter(condition == "THEMATIC") %>%
ggplot(aes(x = control, y = sim_sick.log)) +
ylim(0, 4) +
geom_boxplot(fill = "#009E73", alpha = 0.8) +
labs(title="Thematic", x = "Condition", y = "Simulator Sickness")
ggarrange(sensory.ss.plot, enviro.ss.plot, thematic.ss.plot,
ncol = 3)
```
<!-- We can also remove some outliers here as well, using the same IQR method. -->
<!-- ```{r ss-clean2} -->
<!-- study_data.ss_rm_out <- study_data %>% -->
<!-- filter(sim_sick < median(study_data$sim_sick, na.rm=T) + -->
<!-- 2*IQR(study_data$sim_sick, na.rm=T)) %>% -->
<!-- filter(sim_sick > median(study_data$sim_sick, na.rm=T) - -->
<!-- 2*IQR(study_data$sim_sick, na.rm=T)) -->
<!-- ``` -->
This is certainly better, but we probably still shouldn't assume normality even for the transformed variable. This means using non-parametric tests (below, a Mann-Whitney U Test).
```{r ss-tests}
study_data %>%
wilcox.test(sim_sick ~ control, data =., correct = FALSE, alternative = "less")
study_data %>%
cliffDelta(sim_sick ~ control, data=.)
study_data %>%
filter(condition== "SENSORY") %>%
wilcox.test(sim_sick ~ control, data=., correct = FALSE, alternative = "less")
# Calculate Cliff's delta for effect size
study_data %>%
filter(condition== "SENSORY") %>%
cliffDelta(sim_sick ~ control, data=.)
study_data %>%
filter(condition== "ENVIRONMENTAL") %>%
wilcox.test(sim_sick ~ control, data=., correct = FALSE, alternative = "less")
# Calculate Cliff's delta for effect size
study_data %>%
filter(condition== "ENVIRONMENTAL") %>%
cliffDelta(sim_sick ~ control, data=.)
study_data %>%
filter(condition== "THEMATIC") %>%
wilcox.test(sim_sick ~ control, data=., correct = FALSE, alternative = "less")
# Calculate Cliff's delta for effect size
study_data %>%
filter(condition== "THEMATIC") %>%
cliffDelta(sim_sick ~ control, data=.)
```
It appears that these findings roughly mirror those of the Presence tests, in that only the thematic breach resulted in a significantly higher level of simulator sickness in participants.