---
title: 'Embodiment of the Cinematographer: emotional and perceptual responses to different camera movement techniques'
author: "Yilmaz, Lotman, Karjus, Tikka, 2023"
output: html_document
date: ""
---

This code is to accompany the paper, along with the data, and is provided as-is, without any implication of warranty. Code by Andres Karjus (andreskarjus.github.io). Run all the code blocks to replicate the analyses and plot in the paper. Place the data file (csv) into the working directory, or define a full path below, and install tidyverse and lme4 if not present. lmerTest is optional, providing a more informative summary() function for the mixed models.

# Packages and data

```{r, message=F, warning=F}
# Define the full path to the data file here
datapath="Experiment_dataset.csv"

# Load packages; install those if missing, using install.packages("name")
library(tidyverse) # 2.0.0; dplyr 1.1.0
library(lme4)      # 1.1.30
library(colorspace) # used for plot colors
library(lmerTest) # p-values estimated using Satterthwaite's degrees of freedom method
```


```{r, eval=F, message=F, warning=F}
# Initial data operations; this is left here just for reference; not to be executed
# d = read_delim(datapath, delim = ";") %>% 
#   mutate(MOVEMENT2 = case_when(CAMERA_MOVEMENT=="Static" ~ "_Static", T~"All_moving")) %>% 
#   mutate(CAMERA_MOVEMENT = relevel(as.factor(CAMERA_MOVEMENT), "Static")) %>% 
#   mutate(MOOD = relevel(as.factor(MOOD), "Neutral")) %>% 
#   mutate(AROUSAL=6-AROUSAL, VALENCE=6-VALENCE) # homogenize scale direction
# write_csv(d, "Experiment_dataset.csv")
```


# Load data
```{r, message=F, warning=F}
d = read_csv(datapath) %>%   # and adjust baselines for models and plots:
  mutate(CAMERA_MOVEMENT = relevel(as.factor(CAMERA_MOVEMENT), "Static")) %>% 
  mutate(MOOD = relevel(as.factor(MOOD), "Neutral"))
```


# Statistical modelling

Mood (scene) is treated as a categorical control variable.
```{r}
# valence and arousal
null=lmer(VALENCE~   (1|PARTICIPANT), data=d )
hyp1 = lmer(VALENCE~MOOD + (1|PARTICIPANT), data=d )
hyp2 = lmer(VALENCE~MOVEMENT2 * MOOD + (1|PARTICIPANT), data=d )
anova(null, hyp1, hyp2) %>% print
# summary(hyp2)

null=lmer(AROUSAL~   (1|PARTICIPANT), data=d )
hyp1 = lmer(AROUSAL~MOOD +  (1|PARTICIPANT), data=d )
hyp2 = lmer(AROUSAL~MOOD * MOVEMENT2 +  (1|PARTICIPANT), data=d )
anova(null,hyp1, hyp2) %>% print
# summary(hyp2)

# Q1
null=lmer(Q1~   (1|PARTICIPANT), data=d )
hyp1 = lmer(Q1~MOOD +  (1|PARTICIPANT), data=d )
hyp2 = lmer(Q1~MOOD*MOVEMENT2 +  (1|PARTICIPANT), data=d )
anova(null,hyp1, hyp2) %>% print
# summary(hyp2)

# Q2
null=  lmer(Q2~   (1|PARTICIPANT), data=d )
hyp1 = lmer(Q2~MOOD +  (1|PARTICIPANT), data=d )
hyp2 = lmer(Q2~MOOD * MOVEMENT2 +  (1|PARTICIPANT), data=d )
anova(null,hyp1, hyp2) %>% print
# summary(hyp2)


# Q3 doesn't have static; no dif between cameras
q3d = d %>% filter(MOVEMENT2=="All_moving") %>% 
  mutate(CAMERA_MOVEMENT = relevel(as.factor(CAMERA_MOVEMENT), "Dolly"))
null=  lmer(Q3~   (1|PARTICIPANT), data=q3d )
hyp1 = lmer(Q3~MOOD +  (1|PARTICIPANT), data=q3d )
hyp2 = lmer(Q3~MOOD*CAMERA_MOVEMENT +  (1|PARTICIPANT), data=q3d )
anova(null,hyp1, hyp2) %>% print
# summary(hyp2)

```




# Individual explorative tests
```{r, eval=F}
glm(VALENCE~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Positive") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Dolly" )) ) %>% summary()
glm(AROUSAL~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Positive") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(AROUSAL~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Neutral") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(AROUSAL~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Negative") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q1~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Neutral") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q1~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Positive") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q1~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Negative") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q2~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Neutral") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q2~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Positive") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Static" )) ) %>% summary()
glm(Q3~  CAMERA_MOVEMENT, data=d %>% filter(MOOD=="Negative", CAMERA_MOVEMENT!="Static") %>% mutate(CAMERA_MOVEMENT=relevel(as.factor(CAMERA_MOVEMENT), "Steadicam" )) ) %>% summary()


```

# Plots

```{r, fig.height=3, message=F, warning=F}
# reorganize data
dl = d %>% select(-MOVEMENT2) %>% 
  pivot_longer(
    cols = c(VALENCE, AROUSAL, Q1, Q2, Q3),
    names_to = "QUESTION",
    values_to = "value"
  ) %>% group_by(MOOD, CAMERA_MOVEMENT, QUESTION) %>% 
  summarise(value=mean(value, na.rm=T)) %>% 
  ungroup() %>% 
  mutate(value=round(value,2)) %>% 
  group_by(QUESTION) %>% 
  mutate(valuenorm = scale(value)) %>% 
  ungroup() %>% 
  mutate(MOOD=case_match(MOOD, "Neutral"~"Neutral\nambig.", "Positive"~"Positive\nerotic", "Negative"~"Negative\nhorror")) %>% 
  mutate(QUESTION=case_match(QUESTION,"Q1"~ "Q1 (involvement)", "Q2"~"Q2 (own eyes)", "Q3"~"Q3 (move w/ cam)", "AROUSAL"~"Arousal", "VALENCE"~"Valence")) %>% 
    mutate(CAMERA_MOVEMENT=case_match(CAMERA_MOVEMENT, "Steadicam"~"Steadi\ncam", "Handheld"~"Hand\nheld", .default = CAMERA_MOVEMENT)) %>% 
  mutate(CAMERA_MOVEMENT=fct_relevel(CAMERA_MOVEMENT, "Static")) %>% 
  mutate(QUESTION=fct_relevel(as.factor(QUESTION), "Valence", "Arousal")) 



ggplot(dl, aes(MOOD, CAMERA_MOVEMENT, fill=valuenorm))+
  geom_tile()+
  geom_text(aes(label=value, color=valuenorm), size=4.1)+
  theme_bw(base_size = 14)+
  facet_wrap(~QUESTION, nrow=1)+
  scale_fill_gradientn(colors=c("white", "#8cb8fa" ) %>% lighten(0.1), na.value = "white")+
  scale_color_gradientn(colors=c("white", "#8cb8fa") %>% darken(0.7), na.value = "white")+
  coord_cartesian(expand=0)+
  theme(legend.position = "none",
        axis.ticks = element_blank(),
        axis.title = element_blank(),
        plot.margin = margin(0,0,0,0),
        axis.text.x=element_text(angle=90, hjust=1, vjust=0.4, lineheight=0.8),
        axis.text.y=element_text(lineheight=0.7),
        strip.text = element_text(hjust=0, margin = margin(2, 0,2,0.5))
        )


```

