---
title: "linking gestures"
author: "Marlou"
date: "3-9-2021"
output: html_document
---

```{r}
library(dplyr)
```


```{r}
df_repair_ids <- read.csv2("processing_output/2_repair_speech.csv", header=T, colClasses = c(pairnr = "character")) 
df_speech <- read.csv2("processing_output/1_speech.csv", header=T, colClasses = c(pairnr = "character")) 
df_gestA <- read.csv2("processing_output/1_gestures_A.csv", header=T, colClasses = c(pairnr = "character"))
df_gestB <- read.csv2("processing_output/1_gestures_B.csv", header=T, colClasses = c(pairnr = "character"))
```



#set cols
```{r}
#most cols are factors, change all character cols to factors
df_repair_ids <- df_repair_ids %>% 
  mutate(across(where(is.character), as.factor))

#but set speech and onset/offset cols to character
df_repair_ids <- df_repair_ids %>%
  mutate(A_speech = as.character(A_speech),
          B_speech = as.character(B_speech),
          onset = as.character(onset),
          offset = as.character(offset))


df_speech <- df_speech %>% 
  mutate(across(where(is.character), as.factor))
df_speech <- df_speech %>%
  mutate(A_speech = as.character(A_speech),
          B_speech = as.character(B_speech),
          onset = as.character(onset),
          offset = as.character(offset))


df_gestA <- df_gestA %>% 
  mutate(across(where(is.character), as.factor))
df_gestA <- df_gestA %>%
  mutate( onset = as.character(onset),
          offset = as.character(offset))

df_gestB <- df_gestB %>% 
  mutate(across(where(is.character), as.factor))
df_gestB <- df_gestB %>%
  mutate( onset = as.character(onset),
          offset = as.character(offset))

```



# PUTTING IT ALL TOGETHER
Here we want to accomplish two separate things
1. We want the 'basic'/simple information about gestures added to the complete_df, so that we can easily compute the nr of gestures (and gesture rate) for the repair annotations
2. We want to keep the complete gesture annotations (onset/offset/duration and referent info) for further analyses in a separate df, and those need to be linked to the complete_df (using id_nrs)

# 1. COMPLETE df

```{r}
#gesture dfs, where we will add the 'id' numbers
df_gestA_ids <- df_gestA
df_gestB_ids <- df_gestB

df_gestA_ids$repair_id <- "" #not NA because we use paste later on
df_gestB_ids$repair_id <- ""

df_gestA_ids$repair_overlap <- ""
df_gestB_ids$repair_overlap <- ""

#speech dfs, split by speaker
df_speechA <- subset(df_speech, A_speech!="")
df_speechB <- subset(df_speech, B_speech!="")

#create 'large lists'
df_repair_ids_pairs <- split(df_repair_ids, df_repair_ids$pairnr)
df_gestA_ids_pairs <- split(df_gestA_ids, df_gestA_ids$pairnr)
df_gestB_ids_pairs <- split(df_gestB_ids, df_gestB_ids$pairnr)
df_speechA_pairs <- split(df_speechA, df_speechA$pairnr)
df_speechB_pairs <- split(df_speechB, df_speechB$pairnr)
  
```

```{r}
#count gestures
#two loops: once for ppA and once for ppB

#when to 'assign' a gesture to a repair annotation?
#if:
#main rule:
# - gesture onset (main_rule_a) and/or offset (main_rule_b) falls within repair annotation

#exceptional cases (will be marked for later inspection):
# - gesture onset is max. 2000 msec before repair annotation, and does NOT coincide with prior TCU
#     e.g. pair17, gesture with onset 00:05:17.814 by ppB --> not included in T+1
#     e.g. pair24, three gestures (first with onset 00:07:04.887) by ppB --> included in T0
# - gesture onset is max. 2000 msec after repair annotation, and does NOT coincide with new TCU
#     e.g. pair04, gesture with onset 00:13:15.044 by ppA --> included in T0
#     e.g. pair24, gesture with onset 00:06.01.136 by ppB --> included in T0
#     e.g. pair04, gesture with onset 00:23:06.619 by ppB --> not included in T+1

#and of course the gesture and repair annotation need to be by the same pp



#simple loop, only those that fall within, so both onset and offset within

`%!in%` = Negate(`%in%`)
list_pairnrs = levels(df_repair_ids$pairnr)

for (p in 1:length(list_pairnrs)) { #for every pair:
  p <- list_pairnrs[p]
  print(p)
  list_timestamps_A <- c() #set up empty list for speaker A
  list_timestamps_B <- c() #set up empty list for speaker B
  
  #set up a list with 'speech_timestamps' for speaker A and B: i.e., all the msec between onsets and offsets of speech annotations
  for (t in 1:nrow(df_speechA_pairs[[p]])) 
    {list_timestamps_A <- c(list_timestamps_A, df_speechA_pairs[[p]][t,]$onset_msec:df_speechA_pairs[[p]][t,]$offset_msec)}
  for (t in 1:nrow(df_speechB_pairs[[p]])) 
    {list_timestamps_B <- c(list_timestamps_B, df_speechB_pairs[[p]][t,]$onset_msec:df_speechB_pairs[[p]][t,]$offset_msec)}
  
  
  #loop over df with repair annotations
  for (r in 1:nrow(df_repair_ids_pairs[[p]])) {  
    
    repair_onset <- df_repair_ids_pairs[[p]][r,]$onset_msec #store repair onset
    repair_offset <- df_repair_ids_pairs[[p]][r,]$offset_msec #store repair offset
    
    
  #SPEAKER A
    
     if (!is.na(df_repair_ids_pairs[[p]][r,]$A_speech)) { #if there is speech for A, so if the repair annotation is by A, then loop over gestures by A
       if (p!="10"&p!="18"&p!="19") { #note: ppA of dyads 10, 18 and 19 produces 0 gestures, so don't loop over those!
        for (gA in 1:nrow(df_gestA_ids_pairs[[p]])) { #loop over gestures by A
          
          gest_onset <- df_gestA_ids_pairs[[p]][gA,]$onset_msec #store gest onset
          gest_offset <- df_gestA_ids_pairs[[p]][gA,]$offset_msec #store gest offset
          gest_duration <- gest_offset - gest_onset #store gest duration
          
          if ((repair_onset - gest_onset < 3000)|(gest_onset - repair_offset < 3000)){ #to speed up loop
          
            difference_early <- gest_offset - repair_onset #calculate difference between repair onset and gest offset (early gest)
            prop_early <- difference_early / gest_duration #calculate proportion of gesture that falls within repair boundaries (early gest)
            difference_late <- repair_offset - gest_onset #calculate difference between repair offset and gest onset (late gest)
            prop_late <- difference_late / gest_duration #calculate proportion of gesture that falls within repair boundaries (late gest)
            difference_long <- repair_offset - repair_onset #calculate duration of repair annotation (for long gest)
            prop_long <- difference_long / gest_duration #calculate proportion of gesture that falls within repair boundaries (long gest)
            
            add_id <- paste(df_gestA_ids_pairs[[p]][gA,]$repair_id, df_repair_ids_pairs[[p]][r,]$repair_id) #what to add in case IF true
            add_overlap_part1 <- df_gestA_ids_pairs[[p]][gA,]$repair_overlap
                  
            if (
            #FULLY OVERLAPPING (gest complete within repair boundaries)
              (gest_onset > repair_onset & gest_onset < repair_offset)& #gest onset within repair annotation boundaries
              (gest_offset > repair_onset & gest_offset < repair_offset)) #gest offset also within repair annotation boundaries
              { 
              #add repair_id to that gesture = concatenation of what was there + new id:
              df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
              #add info 'repair_overlap' for further inspection; also concatenation of prior + new overlap type:
              df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1, "complete")} 
            else if (
            #LARGE OVERLAP: gest early
              #gesture start before, ends during repair annotation
              gest_onset < repair_onset & gest_offset > repair_onset & gest_offset < repair_offset & prop_early > 0.5){
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_early")} 
            else if (
            #LARGE OVERLAP: gest late
              #gesture starts during, ends after repair annotation
              gest_onset > repair_onset & gest_onset < repair_offset & gest_offset > repair_offset & prop_late > 0.5){
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_late")}
            else if (
            #LARGE OVERLAP: gest longer
              #gesture starts before repair annotation and ends after repair annotation (so gesture is longer than speech)
              gest_onset < repair_onset & gest_offset > repair_offset & prop_long > 0.5){
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_long")}        
            else if (
            #SMALL OVERLAP + NO SPEECH: gest early
              #gesture starts before repair onset, but not overlapping with other prior speech  
              (gest_offset > repair_onset & gest_offset < repair_offset)& #gest offset within repair annotation boundaries
              (gest_onset < repair_onset & gest_onset %!in% list_timestamps_A)){ #gest onset before repair annotation, but NOT within prior speech TCU
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_early_no_speech")}
            else if (
            #SMALL OVERLAP + NO SPEECH: gest late 
              #gesture ends after repair offset, but not overlapping with other following speech  
              (gest_onset > repair_onset & gest_onset < repair_offset)& #gest onset within repair annotation boundaries
              (gest_offset > repair_offset & gest_offset %!in% list_timestamps_A)){ #gest offset before repair annotation, but NOT within next speech TCU 
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_late_no_speech")}
            else if (
            #SMALL OVERLAP + SPEECH: gest early
              #gesture starts before repair onset, and overlaps with other prior speech  
              (gest_offset > repair_onset & gest_offset < repair_offset)& #gest offset within repair annotation boundaries
              (gest_onset < repair_onset & gest_onset %in% list_timestamps_A)){ #gest onset before repair annotation, but NOT within prior speech TCU
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_early_with_speech")}
            else if (
            #SMALL OVERLAP + SPEECH: gest late 
              #gesture ends after repair offset, and overlaps with other following speech  
              (gest_onset > repair_onset & gest_onset < repair_offset)& #gest onset within repair annotation boundaries
              (gest_offset > repair_offset & gest_offset %in% list_timestamps_A)){ #gest offset before repair annotation, but NOT within next speech TCU 
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_late_with_speech")}
            else if (
            #NO OVERLAP: gest early
              #gesture starts and ends before repair onset (max 2000 msec), but not overlapping with other prior speech
              (gest_onset < repair_onset & gest_offset < repair_onset)& #gest onset and offset before repair annotation
              (repair_onset - gest_offset < 2000)&#but max 2000 msec before
              (gest_onset %!in% list_timestamps_A)& #gest onset NOT during prior speech TCU
              (gest_offset %!in% list_timestamps_A)){ #gest offset NOT during prior speech TCU
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"no_overlap_early")}
            else if (
            #NO OVERLAP: gest late
              #gesture starts and ends after repair onset (max 2000 msec), but not overlapping with other prior speech
              ((gest_onset > repair_offset) & (gest_offset > repair_offset))& #gest onset and offset after repair annotation
              (gest_onset - repair_offset < 2000)&#but max 2000 msec after
              (gest_onset %!in% list_timestamps_A)& #gest onset NOT during prior speech TCU
              (gest_offset %!in% list_timestamps_A)){ #gest offset NOT during prior speech TCU
                      df_gestA_ids_pairs[[p]][gA,]$repair_id <- add_id
                      df_gestA_ids_pairs[[p]][gA,]$repair_overlap <- paste(add_overlap_part1,"no_overlap_late")}
          }
        }
       }
     }
    
    #SPEAKER B
    #repeat same as for A
    
      if (!is.na(df_repair_ids_pairs[[p]][r,]$B_speech)) { 
        for (gB in 1:nrow(df_gestB_ids_pairs[[p]])) { #loop over gestures by B
          
          gest_onset <- df_gestB_ids_pairs[[p]][gB,]$onset_msec #store gest onset
          gest_offset <- df_gestB_ids_pairs[[p]][gB,]$offset_msec #store gest offset
          gest_duration <- gest_offset - gest_onset #store gest duration
          
          if ((repair_onset - gest_onset < 3000)|(gest_onset - repair_offset < 3000)){ #to speed up loop
          
            difference_early <- gest_offset - repair_onset #calculate difference between repair onset and gest offset (early gest)
            prop_early <- difference_early / gest_duration #calculate proportion of gesture that falls within repair boundaries (early gest)
            difference_late <- repair_offset - gest_onset #calculate difference between repair offset and gest onset (late gest)
            prop_late <- difference_late / gest_duration #calculate proportion of gesture that falls within repair boundaries (late gest)
            difference_long <- repair_offset - repair_onset #calculate duration of repair annotation (for long gest)
            prop_long <- difference_long / gest_duration #calculate proportion of gesture that falls within repair boundaries (long gest)
            
            add_id <- paste(df_gestB_ids_pairs[[p]][gB,]$repair_id, df_repair_ids_pairs[[p]][r,]$repair_id) #what to add in case IF true
            add_overlap_part1 <- df_gestB_ids_pairs[[p]][gB,]$repair_overlap
                  
            if (
            #FULLY OVERLAPPING (gest complete within repair boundaries)
              (gest_onset > repair_onset & gest_onset < repair_offset)& #gest onset within repair annotation boundaries
              (gest_offset > repair_onset & gest_offset < repair_offset)) #gest offset also within repair annotation boundaries
              { 
              df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
              df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1, "complete")} 
            else if (
            #LARGE OVERLAP: gest early
              gest_onset < repair_onset & gest_offset > repair_onset & gest_offset < repair_offset & prop_early > 0.5){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_early")} 
            else if (
            #LARGE OVERLAP: gest late
              gest_onset > repair_onset & gest_onset < repair_offset & gest_offset > repair_offset & prop_late > 0.5){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_late")}
            else if (
            #LARGE OVERLAP: gest longer
              gest_onset < repair_onset & gest_offset > repair_offset & prop_long > 0.5){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"L_overlap_long")}        
            else if (
            #SMALL OVERLAP + NO SPEECH: gest early
              (gest_offset > repair_onset & gest_offset < repair_offset)&
              (gest_onset < repair_onset & gest_onset %!in% list_timestamps_B)){ 
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_early_no_speech")}
            else if (
            #SMALL OVERLAP + NO SPEECH: gest late 
              (gest_onset > repair_onset & gest_onset < repair_offset)& 
              (gest_offset > repair_offset & gest_offset %!in% list_timestamps_B)){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_late_no_speech")}
            else if (
            #SMALL OVERLAP + SPEECH: gest early
              (gest_offset > repair_onset & gest_offset < repair_offset)& 
              (gest_onset < repair_onset & gest_onset %in% list_timestamps_B)){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_early_with_speech")}
            else if (
            #SMALL OVERLAP + SPEECH: gest late 
              (gest_onset > repair_onset & gest_onset < repair_offset)& 
              (gest_offset > repair_offset & gest_offset %in% list_timestamps_B)){  
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"S_overlap_late_with_speech")}
            else if (
            #NO OVERLAP: gest early
              (gest_onset < repair_onset & gest_offset < repair_onset)& 
              (repair_onset - gest_offset < 2000)&
              (gest_onset %!in% list_timestamps_B)&
              (gest_offset %!in% list_timestamps_B)){ 
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"no_overlap_early")}
            else if (
            #NO OVERLAP: gest late
              ((gest_onset > repair_offset) & (gest_offset > repair_offset))&
              (gest_onset - repair_offset < 2000)&
              (gest_onset %!in% list_timestamps_B)&
              (gest_offset %!in% list_timestamps_B)){
                      df_gestB_ids_pairs[[p]][gB,]$repair_id <- add_id
                      df_gestB_ids_pairs[[p]][gB,]$repair_overlap <- paste(add_overlap_part1,"no_overlap_late")}
        }
        }
      }
     }
}



```



```{r}
df_gestA_ids <- do.call("rbind", df_gestA_ids_pairs)
df_gestB_ids <- do.call("rbind", df_gestB_ids_pairs)


df_gest_complete <- bind_rows(df_gestA_ids, df_gestB_ids)
df_gest_complete <- subset(df_gest_complete, df_gest_complete$repair_id!="")

table(df_gest_complete$repair_overlap)
```

#manual cleaning
```{r}
#first, for 4 categories the gestures have been inspected in ELAN to determine whether they correspond to the repair TCU or not.
#For the following gestures that was *not* the case and thus should be taken out of the df:

#'no_overlap_early'
df_gest_complete[df_gest_complete$pairnr=="04"&df_gest_complete$onset_msec==668708,]$repair_id <- NA
#'no_overlap_late'
df_gest_complete[df_gest_complete$pairnr=="04"&df_gest_complete$onset_msec==1174522,]$repair_id <- NA
df_gest_complete[df_gest_complete$pairnr=="15"&df_gest_complete$onset_msec==477497,]$repair_id <- NA
df_gest_complete[df_gest_complete$pairnr=="24"&df_gest_complete$onset_msec==195987,]$repair_id <- NA
#'S_overlap_early_with_speech'
df_gest_complete[df_gest_complete$pairnr=="09"&df_gest_complete$onset_msec==297318,]$repair_id <- NA
df_gest_complete[df_gest_complete$pairnr=="17"&df_gest_complete$onset_msec==317814,]$repair_id <- NA

df_gest_complete <- subset(df_gest_complete, !is.na(repair_id))

#then, some gestures have 'no overlap' with one and 'small/large overlap' with another repair annotation
#there we have to set to which one it belongs:
df_gest_complete[df_gest_complete$pairnr=="04"&df_gest_complete$onset_msec==795044,]$repair_id <- 17
df_gest_complete[df_gest_complete$pairnr=="04"&df_gest_complete$onset_msec==795044,]$repair_overlap <- "no_overlap_late"
df_gest_complete[df_gest_complete$pairnr=="11"&df_gest_complete$onset_msec==280548,]$repair_id <- 305
df_gest_complete[df_gest_complete$pairnr=="11"&df_gest_complete$onset_msec==280548,]$repair_overlap <- "no_overlap_late"
df_gest_complete[df_gest_complete$pairnr=="16"&df_gest_complete$onset_msec==628924,]$repair_id <- 611
df_gest_complete[df_gest_complete$pairnr=="16"&df_gest_complete$onset_msec==628924,]$repair_overlap <- "L_overlap_early"
df_gest_complete[df_gest_complete$pairnr=="18"&df_gest_complete$onset_msec==600793,]$repair_id <- 668
df_gest_complete[df_gest_complete$pairnr=="18"&df_gest_complete$onset_msec==600793,]$repair_overlap <- "L_overlap_late"


```

#clean up
```{r}
df_gest_complete$repair_overlap <- trimws(df_gest_complete$repair_overlap, "l")
df_gest_complete$repair_overlap <- trimws(df_gest_complete$repair_overlap, "r")
df_gest_complete$repair_id <- trimws(df_gest_complete$repair_id, "l")
df_gest_complete$repair_id <- trimws(df_gest_complete$repair_id, "r")


df_gest_complete$repair_overlap <- as.factor(df_gest_complete$repair_overlap)

```


```{r}
table_overlap <- data.frame(table(df_gest_complete$repair_overlap))
names(table_overlap)[1] <- "overlap_category"
names(table_overlap)[2] <- "count"
```

#export
```{r}
write.csv2(df_gest_complete, "processing_output/3_gestures.csv", row.names=F)
write.csv2(table_overlap, "processing_output/3_table_linked_gestures.csv", row.names=F)
```


