Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/craddm/eegUtils into dev…
Browse files Browse the repository at this point in the history
…elop
  • Loading branch information
craddm committed Sep 13, 2023
2 parents 41cd60d + 5f2e4f4 commit ecf47fb
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 21 deletions.
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ S3method(eeg_reference,default)
S3method(eeg_reference,eeg_ICA)
S3method(eeg_reference,eeg_data)
S3method(eeg_reference,eeg_epochs)
S3method(eeg_summarise,default)
S3method(eeg_summarise,eeg_epochs)
S3method(electrode_locations,data.frame)
S3method(electrode_locations,eeg_data)
S3method(electrode_locations,eeg_epochs)
Expand Down Expand Up @@ -226,6 +228,7 @@ export(eeg_downsample)
export(eeg_epochs)
export(eeg_filter)
export(eeg_reference)
export(eeg_summarise)
export(electrode_locations)
export(epoch_data)
export(epoch_stats)
Expand Down
1 change: 1 addition & 0 deletions R/plot_gfp.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#' separately for different conditions.
#' @param keep_trials Calculate GFP for each epoch separately, then average over
#' epochs.
#' @author Matt Craddock \email{matt@@mattcraddock.com}
#' @export
#' @examples
#' plot_gfp(demo_spatial)
Expand Down
145 changes: 145 additions & 0 deletions R/summarise_eeg.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#' Calculate simple summary statistics for `eeg_*` objects
#'
#' Calculate the timepoint-by-timepoint mean, standard deviation, standard
#' error, or variance `eeg_epochs` objects.
#'
#' @param data An `eegUtils` object.
#' @param ... Various arguments passed to specific functions
#' @return A tibble
#' @export
eeg_summarise <- function(data,
...) {
UseMethod("eeg_summarise", data)
}

#' @export
eeg_summarise.default <- function(data,
...) {
stop("Not implemented for objects of class ",
paste(class(data), collapse = "/"))
}

#' @param statistic The statistic to calculate at each timepoint. Defaults to
#' "sem"
#' @param conditions Conditions to group the data by.
#' @param time_lim Timepoint(s) to summarise. Can be a range, for which a
#' summary statistic will be provided for each timepoint, or a list of
#' individual times. If none is supplied, the function will calculate a
#' summary for every timepoint.
#' @describeIn eeg_summarise Calculate summary statistics for `eeg_epochs`
#' objects
#' @export
eeg_summarise.eeg_epochs <- function(data,
statistic = c("sem",
"mean",
"sd",
"var"),
conditions = NULL,
time_lim = NULL,
...) {

if (!is.null(conditions)) {
groups <- c(conditions, "time")
} else {
groups <- "time"
}

chans <- channel_names(data)
data <- as.data.frame(data)

if (!is.null(time_lim)) {
data <- select_times(data,
time_lim)
}

data <- dplyr::group_by(data,
dplyr::across({{ groups }}))

summary_function <-
switch(statistic,
mean = function(x) mean(x),
sem = function(x) sd(x) / length(x),
sd = function(x) sd(x),
var = function(x) var(x)
)

data <- dplyr::summarise(
data,
dplyr::across(chans,
summary_function,
.names = paste(statistic,
sep = "_",
"{.col}")
)
)
data
}

#' Calculate the standard error of the mean
#'
#' @param data An `eegUtils` object
#' @param time_lim A vector of time-points to calculate SEM over.
#' @param conditions Split the calculation across multiple conditions
#' @keywords internal

calculate_sem <- function(data,
time_lim = NULL,
conditions = NULL) {

conditions <- rlang::enquo(conditions)
chans <- channel_names(data)

if (is.list(time_lim)) {
all_sems <- lapply(time_lim,
function(x) calculate_sem(data,
time_lim = x,
conditions = {{conditions}}))
return(
do.call("rbind",
all_sems)
)

} else {
data <- select_times(data,
time_lim)
}
data <- as.data.frame(data)

if (!is.null(conditions)) {
data <- group_by(data,
{{conditions}},
.data$epoch)
}
data <- dplyr::summarise(
data,
dplyr::across(chans,
mean))
data <- dplyr::summarise(
data,
count = length(unique(.data$epoch)),
dplyr::across(chans,
list(sem = ~sd(.) / sqrt(count))))
data$time_lim <- list(time_lim)
data
}

calculate_sd <- function(data,
time_lim,
conditions = NULL) {
conditions <- rlang::enquo(conditions)
chans <- channel_names(data)
data <- select_times(data,
time_lim)
data <- as.data.frame(data)
if (!is.null(conditions)) {
data <- group_by(data,
{{conditions}})
}
data <- dplyr::summarise(
data,
count = length(unique(.data$epoch)),
dplyr::across(chans,
list(sd = ~sd(.))))
data$time_lim <- list(time_lim)
data
}
2 changes: 1 addition & 1 deletion R/topoplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ topoplot.default <- function(data,
#' @import tidyr
#' @family scalp-based maps
#' @describeIn topoplot Topographical plotting of data.frames and other non
#' eeg_data objects.
#' `eeg_data` objects.
#' @export

topoplot.data.frame <- function(data,
Expand Down
125 changes: 125 additions & 0 deletions docs/dev/reference/calculate_sem.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions man/calculate_sem.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions man/eeg_filter.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions man/eeg_summarise.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ecf47fb

Please sign in to comment.