Skip to content

Commit

Permalink
Update behavioral preprocessing notebook with relying on new script s…
Browse files Browse the repository at this point in the history
…ource
  • Loading branch information
aridyckovsky committed May 11, 2021
1 parent a01d2cb commit 59ab527
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 221 deletions.
59 changes: 59 additions & 0 deletions R/behavioral_data_preprocessing.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#' @title Get hit times vector from signals and responses per participant
#' @description This function uses input of both signal times and response times
#' from a single participant's extracted behavioral data to determine the hit
#' indices, if any, and in turn, the hit times.
#' Get hit timestamp from a vector of signal times and a vector of response times
#' @note Use the .interval variable if 8 seconds is not the desired interval
#' @export
get_hit_times <- function(signal_times, response_times, .interval = 8.0) {
signal_times %>%
map_dbl(function(signal_time) {

hit_index <- first(which(
response_times %>%
map_lgl(~ between(.x, signal_time, signal_time + .interval)),
arr.ind = TRUE
))

hit_time <- response_times[hit_index]

return(hit_time)

})
}

#' @title Get all participants' hits with reaction times
#' @description Creates a dataframe composed of each participant's hit times and
#' reaction times for those hits, row-by-row with signal times.
#' @export
get_all_hits_with_reaction_times <- function(participants, combined_df) {

# Extract only rows where a signal is present
all_signals_df <- combined_df %>%
filter(is_signal == 1) %>%
mutate(
signal_time = step_time
) %>%
select(trial, id, image_index, signal_time)

# Extract only rows where a response attempt is present
all_responses_df <- combined_df %>%
filter(is_response == 1) %>%
select(trial, id, image_index, resp_time)

# Map over the unlisted participants' ids to get the per-participant
# signals and responses, then return a combined dataframe of all participant
# including trial rows for signals, and if it exists, hit time and reaction time
map_dfr(unlist(participants), function(participant) {
signals <- all_signals_df %>%
filter(id == participant)

responses <- all_responses_df %>%
filter(id == participant)

signals %>% mutate(
hit_time = get_hit_times(signals$signal_time, responses$resp_time),
reaction_time = hit_time - signal_time
)
})
}
97 changes: 27 additions & 70 deletions notebooks/behavioral_data_preprocessing.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -74,75 +74,12 @@ combined_df %>%

## Function definitions

The function to get each participant's hit time:

```{r}
HIT_INTERVAL <- 8
# Get hit timestampe from a vector of signal times and a vector of response times
# Use the .interval variable if HIT_INTERVAL is not defined or a different hit interval is desired
get_hit_time <- function(signal_times, response_times, .interval = HIT_INTERVAL) {
signal_times %>%
map_dbl(function(signal_time) {
hit_index <- first(which(
response_times %>%
map_lgl(~ between(.x, signal_time, signal_time + .interval)),
arr.ind = TRUE
))
hit_time <- response_times[hit_index]
return(hit_time)
})
}
```

The function to get a dataframe of combined hits, including the hit time itself,
and the reaction time between that hit time and the signal prompting that response.

```{r}
# Get combined hits dataframe composed of each participant's hit times and
# reaction times for those hits, row-by-row with signal times.
# Uses both combined signals and responses
get_combined_hits <- function(participants, combined_df) {
# Extract only rows where a signal is present
combined_signals_df <- combined_df %>%
filter(is_signal == 1) %>%
mutate(
signal_time = step_time
) %>%
select(trial, id, image_index, signal_time)
# Extract only rows where a response attempt is present
combined_responses_df <- combined_df %>%
filter(is_response == 1) %>%
select(trial, id, image_index, resp_time)
# Map over the unlisted participants' ids to get the per-participant
# signals and responses, then return a combined dataframe of all participant
# including trial rows for signals, and if it exists, hit time and reaction time
map_dfr(unlist(participants), function(participant) {
participant_signals <- combined_signals_df %>%
filter(id == participant)
participant_responses <- combined_responses_df %>%
filter(id == participant)
participant_signals %>% mutate(
hit_time = get_hit_time(participant_signals$signal_time, participant_responses$resp_time),
reaction_time = hit_time - signal_time
)
})
}
```
The function to get each participant's hit times vector is `itrackvalr::get_hit_times`, and the function to get a dataframe of all participants' hits is `itrackvalr::get_all_hits_with_reaction_times`, including each hit time and reaction time between that hit time and the nearest signal prompting a response within a fixed interval.

## Get the combined hits using the function

```{r}
combined_hits_df <- get_combined_hits(participants, combined_df)
combined_hits_df <- get_all_hits_with_reaction_times(participants, combined_df)
```

## Check out a quick preview of the table of hits
Expand All @@ -168,9 +105,9 @@ knitr::kable(head(
))
```

## Show plot of reaction times by signal times
## Gut-check plot of reaction times by signal times

For hits, the reaction time does increase slightly across all participants.
Note the 1.000s to 1.100s gap where hits were not recorded.

```{r}
combined_hits_df %>%
Expand All @@ -181,9 +118,29 @@ combined_hits_df %>%
theme_classic()
```

## Reaction times per participant centered at the median




```{r, fig.height = 10, fig.width = 10}
combined_hits_df %>%
drop_na() %>%
arrange(reaction_time) %>%
ggplot(aes(x = reorder(id, reaction_time, FUN = median), y = reaction_time)) +
geom_point(alpha = 0.8, size = 0.7, color = 'darkblue', position = 'jitter') +
geom_boxplot(alpha = 0) +
geom_hline(yintercept = 1, color = 'coral') +
theme_minimal() +
theme(
aspect.ratio = 1,
text = element_text(size = 15),
plot.margin = margin(18, 18, 18, 18, 'pt')
) +
labs(
title = 'Reaction times of participants by id',
subtitle = 'Boxplot per participant anchored at median of reaction time',
y = 'Reaction time for HIT after double-tick signal',
x = 'Participant'
) +
coord_flip()
```


Loading

0 comments on commit 59ab527

Please sign in to comment.