```{r}
#Change to your own directory (where you keep the data file)
dir = 'C:\\Users\\yoav\\Documents\\bigfiles\\qualtrics.iat'
```

```{r}
# Copied from Elad Zlotnick (from here: https://github.com/eladzlot/minnojs-qiat/blob/master/qiat.R)
# Parse csv generated by minnoJS
#
# @param df a data frame
# @param id the column name holding the ids
# @param data the column name holding the data (we assume the data holds an array of unnested objects)
#
# @example
# qiat.parse.quoted(df, 'ResponseId', 'Q_47')
# qiat.parse(df, ResponseId, Q_47)
#
# @returns data frame with parsed data, rows with NA or '' are omitted.
qiat.parse.quoted = function(df, id, data){
  # @TODO does not work?
  # if (is.factor(df[id])) stop(paste0(data, ' column must not be a factor'))
  filteredDF = df[df[,data]!='' & !is.na(df[,data]) ,]
  
  # parse data -> list of data data frames
  csvList = lapply(filteredDF[,data], function(str) tryCatch({
    read.csv(text=str,stringsAsFactors = FALSE)
  },
  error = function(err){
    message('woa there is a malformed csv here')
    return(NA)
  }
  ))
  #browser()
  # add id to each data DF
  mask = which(sapply(csvList,nrow)>0)
  dataPages = mapply(
    function(id, df) cbind(id,df),
    filteredDF[mask,id],
    csvList[mask],
    SIMPLIFY = FALSE
  )
  
  if (!length(dataPages)) { return(data.frame()) }
  
  # concat pages
  do.call(rbind,dataPages)
}

qiat.parse = function(df, id, data){
  qiat.parse.quoted(df, deparse(substitute(id)), deparse(substitute(data)))
}
```

```{r}
#Read your file here.
#df = read.csv(paste(dir, 'Minno IAT_March 5, 2020_11.37.csv',sep = '\\'))
df = read.csv(paste(dir, 'demo gender science IAT_March 9, 2020_10.40.csv',sep = '\\'))
```


```{r}
#The escaping in the data sometimes uses "" which we need to change to " for the parsing.
#Note Q3 in my data was the columns that saved the IAT data for each participant. It might have a different name in your data. 
library(kutils)
df$IAT <- mgsub(df$Q3, pattern = c('""'), replacement = c('"'))
```

```{r}
#Use Elad's parsing function
df2 <- qiat.parse.quoted(df = df, id='ResponseId', data = 'IAT')
```

```{r}
#Sanity check: see the names of the variables.
nrow(df2)
names(df2)
#If successful, these should be:  "id"    "block" "trial" "cond"  "comp"  "type"  "cat"   "stim"  "resp"  "err"   "rt"    "d"     "fb"    "bOrd" 
```


```{r}
#Keep only the critical blocks
iat.raw <- df2[which(df2$block %in% c(3,4,6,7)),]
#Sanity check: need to include only "incompatible" and "compatible"
table(iat.raw$comp, exclude=NULL)
#Make sure the 'compatible' trials are indeed what you expected them to be.
table(iat.raw$comp, iat.raw$cond, exclude=NULL)
```

```{r}
#The combination of compatibility condition and block number determined the blockName for the IAT scoring function.
iat.raw$blockName <- ifelse(iat.raw$comp == 'compatible', 
                            ifelse(iat.raw$block %in% c(3,6), "B3", 
                                   ifelse(iat.raw$block %in% c(4,7), "B4", NA)), 
                            ifelse(iat.raw$comp == 'incompatible', 
                                   ifelse(iat.raw$block %in% c(3,6), "B6", 
                                          ifelse(iat.raw$block %in% c(4,7), "B7", NA)), NA))
#Make sure you only have B3,B4,B6, and B7 and no NAs.
table(iat.raw$blockName, exclude=NULL)
#Not supposed to have any NA at this point. So, if you see <NA> here, investigate why 
#(e.g., perhaps some of your data has different cond values than expected, if you changed the cond after running a few participants)
iat.raw <- iat.raw[which(!is.na(iat.raw$blockName)),]
```

```{r}
#Verify that both are numbers (probably, integer)
class(iat.raw$rt)
class(iat.raw$err)
```

```{r}
##Sanity check. For each participant, we expect a certain number of trials for in each block. 
##We will indicate whether the participant has the expected number of trials within each of the critical block.
library(doBy)
nTrials.long <- summaryBy(formula = err ~ id + blockName, data=iat.raw, FUN = length)
library(reshape2)
nTrials <- dcast(nTrials.long, id ~ blockName, value.var = 'err.length')
#You can change those number if your IAT had different numbers
library(dplyr)
nTrials <- nTrials %>% 
  mutate(ntrials.ok = case_when(
    nTrials$B3==20 & nTrials$B4==40 & nTrials$B6==20 & nTrials$B7==40 ~ TRUE,
    TRUE ~ FALSE
  ))
#If not all are TRUE, then you some participants are missing data
table(nTrials$ntrials.ok, exclude=NULL)
```

```{r}
library(IAT)
iatscore <- cleanIAT(iat.raw, block_name="blockName", 
                     trial_blocks = c("B3", "B4", "B6", "B7"), 
                     session_id="id", 
                     trial_latency="rt",
                     trial_error = "err", 
                     v_error=2, v_extreme=2, v_std=1) 
#v_error=2 means recode error latency to m+600, v_error=1 mean the standard (onset of stimuli until the correct response is pressed). v_extreme=2(current standard)=delete trial latencies < 400ms. v_std=1 (current standard), block SD is performed including error trials 

#How many participants were excluded for problematic performance?
table(iatscore$SUBEXCL, exclude=NULL)
#Summary of those who were not excluded.
summary(iatscore$IAT[which(iatscore$SUBEXCL==0)])
```

```{r}
##Simple graph
library(ggplot2)
iatscore$dummy <- ''
box_plot <- ggplot(iatscore, aes(x = dummy, y = IAT))
box_plot +
  geom_boxplot() +
  geom_dotplot(binaxis = 'y',
               dotsize = 0.4,
               stackdir = 'center') +
  theme_classic() + 
  stat_summary(geom = "point", fun.y = "mean", col = "black", size = 3, shape = 24, fill = "grey")
iatscore$dummy <- NULL
```

```{r}
#Get the bord variable
block.order1 <- df2[which(!is.na(df2$bOrd) & nchar(df2$bOrd)>0),c('id', 'bOrd')]
table(block.order1$bOrd, exclude=TRUE)

#Also get the block order condition from the raw data
block.order2 <- df2[which(df2$block==3),c('id','cond','comp')]

block.order2 <- unique(block.order2)
names(block.order2) <- c('id', 'block3Cond', 'block3Comp')

#Should be TRUE if all is fine.
length(unique(block.order2$id)) == nrow(block.order2)

#Should be TRUE if all is fine.
nrow(block.order1) == nrow(block.order2)

block.order <- merge(block.order1, block.order2, by='id')
table(block.order$bOrd, block.order$block3Cond, exclude=NULL)
```

