R/ANT-functions.R

Defines functions ANT_calculator Attention_systems_calculator calc_systems eprime_to_dataframe

Documented in ANT_calculator Attention_systems_calculator calc_systems eprime_to_dataframe

#' An Eprime conversion function
#' 
#' A function to convert eprime text files to r dataframes
#' This function converts eprime data into R usable dataframes. It will take in .eprime files, and will return a dataframe.
#' @param wm_path specifies the file path to the eprime file of interest
#' @export
#' @return dataframe containing all eprime entries for Accuracy, Reaction time (RT), and Warning type
#' @keywords eprime, dataframe

eprime_to_dataframe <- function(wm_path) {
  # Read in a text file generated by Eprime
  wm_lines <- rprime::read_eprime(wm_path)
  # Convert lines from an Eprime file into EprimeFrame objects
  wm_frames <- rprime::FrameList(wm_lines)
  # Make it a data frame.
  experiment_df <- rprime::to_data_frame(wm_frames)
  
  
  # Select the columns we want for a tibble called "dat".
  experiment_df <- experiment_df %>%
    dplyr::select(FlankerType,SlideTarget.ACC, SlideTarget.RT, WarningType) %>%
    
    # Convert data types 
    dplyr::mutate(SlideTarget.ACC = as.numeric(SlideTarget.ACC), 
           SlideTarget.RT = as.numeric(SlideTarget.RT),
           
           # characterize cue type 
           cue = ifelse(WarningType == "up" | WarningType == "down", "orienting", WarningType),
           )
  # find the length of a third of the experiment
  third_length <- floor(nrow(experiment_df)/3)
  # add new column classifying which third the observation was in
  experiment_df$third <- if((3* third_length) == nrow(experiment_df)) {
    rep(1:3, third_length)
  } else {
      c(rep(1, third_length), rep(2, third_length), rep(3, nrow(experiment_df) - (2* third_length)))
    } 
  # return the experiment df
  experiment_df
}


#' Median response time calcualtor
#'
#' A function that calculates median values of repsonse times from ANT data with the option to split data into thirds or take the median over all observations.
#' @param df the dataframe containing ANT data for calculating median reaction times
#' @param thirds specifies whether the medians should be calculated for eacah third of the observation time separately. Default is FALSE.
#' @return Returns median(s) reaction times for the specified subject as a dataframe 
#' @export

calc_systems <- function(df, thirds = FALSE) {
  gr <- NULL
  gr <- if(thirds == TRUE) {quote(third)} else {third <-0 }
  
  # compute median overall RT and accuracy
  ACC <- df %>%
    dplyr::group_by(!!gr) %>%
    dplyr::summarize("acc" = mean(SlideTarget.ACC, na.rm = TRUE))
  RT <- df %>%
    dplyr::group_by(!!gr) %>%
    dplyr::summarize("rt" = median(df$SlideTarget.RT, na.rm=TRUE))
  
  # find medians of cues 
  medians <- df %>%
    # Filter only accurate attempts
    dplyr::filter(SlideTarget.ACC == 1) %>%
    dplyr::group_by(cue, !!gr)%>%
    
    # find the medians
    dplyr::summarize(med = median(SlideTarget.RT, na.rm = TRUE)) %>%
    tidyr::pivot_wider(names_from = cue, values_from=med)
  
    # All calculations are done on medians for stability since these distributions are often quite skewed.
  
  # Calculate alerting
  # Cues: No - double  
  alerting <- medians["no"] - medians["double"]
  
  # Calculate Orienting  
  # Cues: Center - Orienting
  orienting <- medians["center"] - medians["orienting"]
  
  # Calculate conflict
  # Flankertype: Incongruent - congruent
  conflict <- df %>%
    # Filter for the correct cues and only accurate attempts
    dplyr::filter(FlankerType == "incongruent" | FlankerType == "congruent" & SlideTarget.ACC == 1) %>%
    dplyr::group_by(FlankerType, !!gr) %>%
    
    # find the medians
    dplyr::summarize(med = median(SlideTarget.RT, na.rm = TRUE)) %>%
    
    tidyr::pivot_wider(names_from = FlankerType, values_from = med) %>%
    
    # take the difference of the medians
    dplyr::mutate(conflict = incongruent - congruent)
    
  results <- dplyr::tibble("Alert" = alerting$no, "Orient" = orienting$center, "Conflict" = conflict$conflict,
                    "ACC" = ACC$acc, "Median_RT" = RT$rt)
  results$Third <- if(thirds == TRUE) {1:nrow(results)} else {0}
  
  # return resutls
  results
}

#' Attention systems calculator 
#'
#' A function that loads eprime data and calculates median response times from ANT data with the option to split data into thirds or take the median over all observations.
#' @param file specifies the file path to the eprime file of interest 
#' @param thirds specifies whether the medians should be calculated for eacah third of the observation time separately. Default is FALSE.
#' @return Returns median(s) reaction times for the specified subject as a dataframe 
#' @export

Attention_systems_calculator <- function(file, thirds = FALSE) {
  # convert eprime text to dataframe
  dat <- eprime_to_dataframe(file)
  
  # attach subject grid
  # note that it references the "i" from the higher up for loop
  subject <- stringr::str_extract(file, "-[:alnum:]*")
  subject <- sub(".", "", subject)
  
  # attach year of observation
  year <- stringr::str_extract(file, "[1-3]")
  
  
  # Calculate and return results
  results <- calc_systems(dat, thirds)
  cbind(subject, year, results)
}

#' Complete Attention systems calculator 
#'
#' A function that computes all of the ANT metrics for an entire folder of eprime data. Reteurns both  summarries for 
#' thirds of the experiment and for the whole observation (when thirds =0)
#' @param folder specifies the folder with the ANT data which you want to compute over. If unspecified it enters
#'               an interactive interface to select the directory
#' @param out specifies where to save results, default is to not save output 
#' @return Returns Attention systmes metrics as well as Accuracy, reaction time, and corresponding third of experimetn metrics was computed off of for all subjects in the speciffied folder 
#'         Thirds refer to which third of the experimetnt the summariaes were calculated from. 0 refers to using the whole observation
#' @export


ANT_calculator <- function(folder = "NULL", out="NULL") {
  # if user doesn't define folder, have them select it
  if (folder == "NULL") {
    ANT_folder <- rstudioapi::selectDirectory()
  } else {
    ANT_folder <- folder
  }
  # Extract the files in that folder 
  files <- list.files(ANT_folder, full.names = TRUE)
  # select only the .txt files
  files <- files[grepl("*.txt$", files)]
  # Seed empty results dataframe to input results
  results <- data.frame()
  
  
  # compute attention network metrics for each experiment
  for (i in 1:(length(files))) {
   print(paste("Processing experiment", i))
   results <- rbind(results, Attention_systems_calculator(files[[i]], thirds = FALSE))
   results <- rbind(results, Attention_systems_calculator(files[[i]], thirds = TRUE))
  }
  
  #r1 <- results
  #r2 <- results
  #r3 <- results
  #### This is for storing and combining results from multiple years.
   
  #results <- rbind(r1, r2, r3)
  
  # save results as a csv if you want.
  if (out != "NULL") {
    write.csv(results, out) 
  }
  # return results
  results
}
coffm049/RAD.Lab documentation built on April 4, 2022, 10:35 a.m.