/
deprecated.R
217 lines (191 loc) · 6.48 KB
/
deprecated.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#'@rdname ar_FASTER
#'@export
eeg_FASTER <- function(data, ...) {
.Deprecated("ar_FASTER",
msg = "Please use ar_FASTER; eeg_FASTER will be removed in a forthcoming release.")
ar_FASTER(data, ...)
}
#'@rdname eeg_reference
#'@export
reref_eeg <- function(data, ...) {
.Deprecated("eeg_reference",
msg = "reref_eeg has been renamed eeg_reference, and will be removed in a future version of eegUtils.")
eeg_reference(data, ...)
}
#' Butterworth IIR filter
#'
#' Construct a Butterworth IIR filter and filter input data. This uses
#' `signal::filt_filt`, which filters the signal twice to - once forwards,
#' then again backwards).
#'
#' low_freq and high_freq are passband edges. Pass low freq or high freq alone
#' to perform high-pass or low-pass filtering respectively. For band-pass or
#' band-stop filters, pass both low_freq and high_freq.
#'
#' If low_freq < high_freq, bandpass filtering is performed.
#'
#' If low_freq > high_freq, bandstop filtering is performed.
#'
#' Note that the signal is first zero-meaned using either channel means or
#' by-channel epoch means.
#' @examples
#' plot_psd(iir_filt(demo_epochs, low_freq = 1, high_freq = 30))
#' plot_psd(iir_filt(demo_epochs, low_freq = 12, high_freq = 8))
#' @author Matt Craddock \email{matt@@mattcraddock.com}
#' @param data Data to be filtered.
#' @param ... Parameters passed to S3 methods
#' @export
iir_filt <- function(data, ...) {
UseMethod("iir_filt", data)
}
#' @export
iir_filt.default <- function(data, ...) {
stop("Function works on data.frames, eeg_data, and eeg_epochs.")
}
#' @param low_freq Low passband edge.
#' @param high_freq High passband edge.
#' @param filter_order Order of the Butterworth filter.
#' @param srate Sampling rate of the signal.
#' @param silent Turns off filtering messages.
#' @importFrom signal butter filtfilt freqz
#' @importFrom purrr map_df
#' @export
#' @describeIn iir_filt Filter a data frame
iir_filt.data.frame <- function(data,
low_freq = NULL,
high_freq = NULL,
filter_order = 4,
srate,
silent = FALSE,
...) {
if (missing(srate)) {
stop("sampling rate must be supplied.")
}
data <- run_iir(data,
low_freq,
high_freq,
filter_order,
srate,
silent = silent)
data
}
#' @export
#' @describeIn iir_filt Filter `eeg_data` objects
iir_filt.eeg_data <- function(data,
low_freq = NULL,
high_freq = NULL,
filter_order = 4,
silent = FALSE,
...) {
data$signals <- run_iir(data$signals,
low_freq,
high_freq,
filter_order,
data$srate,
silent = silent)
data
}
#' @export
#' @describeIn iir_filt Filter `eeg_epochs` objects.
iir_filt.eeg_epochs <- function(data,
low_freq = NULL,
high_freq = NULL,
filter_order = 4,
silent = FALSE,
...) {
data$signals$epoch <- data$timings$epoch
data$signals <- run_iir(data$signals,
low_freq,
high_freq,
filter_order,
data$srate,
silent = silent)
data$signals["epoch"] <- NULL
data
}
#' Internal function for running IIR filtering
#'
#' @param data Data to be filtered
#' @param low_freq Low passband edge.
#' @param high_freq High passband edge.
#' @param filter_order Order of the Butterworth filter.
#' @param srate Sampling rate of the signal.
#' @param silent Turns off filtering messages.
#' @importFrom dplyr group_by
#' @importFrom purrr map_df
#' @importFrom signal filtfilt butter
#' @keywords internal
run_iir <- function(data,
low_freq = NULL,
high_freq = NULL,
filter_order,
srate,
silent = FALSE) {
if (filter_order < 2 || filter_order > 20) {
stop("Filter order should be between 2 and 20.")
}
if (length(low_freq) > 1 | length(high_freq) > 1) {
stop("Only one number should be passed to low_freq or high_freq")
}
if (is.null(low_freq) & is.null(high_freq)) {
stop("At least one frequency must be specified.")
}
if (is.null(low_freq)) {
filt_type <- "low"
message(sprintf("Low-pass IIR filter at %.4g Hz", high_freq))
W <- high_freq / (srate / 2)
} else if (is.null(high_freq)) {
filt_type <- "high"
message("High-pass IIR filter at ", low_freq," Hz")
W <- low_freq / (srate / 2)
if (length(dim(data)) > 1) {
data <- sweep(data,
2,
colMeans(data))
} else {
data <- data - mean(data)
}
} else if (low_freq > high_freq) {
filt_type <- "stop"
message(sprintf("Band-stop IIR filter from %.4g-%.4g Hz",
high_freq, low_freq))
W <- c(high_freq / (srate / 2),
low_freq / (srate / 2))
if (length(dim(data)) > 1) {
data <- sweep(data,
2,
colMeans(data))
} else {
data <- data - mean(data)
}
} else if (low_freq < high_freq) {
filt_type <- "pass"
message(sprintf("Band-pass IIR filter from %.4g-%.4g Hz",
low_freq, high_freq))
W <- c(low_freq / (srate / 2),
high_freq / (srate / 2))
if (length(dim(data)) > 1) {
data <- sweep(data, 2, colMeans(data))
} else {
data <- data - mean(data)
}
}
#filtfilt filters twice, so effectively doubles filter_order - we half it here
#so that it corresponds to the expectation of the user
filter_order <- round(filter_order / 2)
filt_coef <- signal::butter(filter_order,
W,
type = filt_type)
data <- data.table(data)
if ("epoch" %in% names(data)) {
data <- data[,
lapply(.SD,
function(x) signal::filtfilt(filt_coef, x)),
by = epoch]
} else {
data <- data[,
lapply(.SD,
function(x) signal::filtfilt(filt_coef, x))]
}
tibble::as_tibble(data)
}