| Title: | Toolkit for Electroencephalography Data |
|---|---|
| Description: | Analysis and visualization tools for electroencephalography (EEG) data. Includes functions for (i) plotting EEG data, (ii) filtering EEG data, (iii) smoothing EEG data; (iv) frequency domain (Fourier) analysis of EEG data, (v) Independent Component Analysis of EEG data, and (vi) simulating event-related potential EEG data. |
| Authors: | Nathaniel E. Helwig [aut, cre] |
| Maintainer: | Nathaniel E. Helwig <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 1.0-5 |
| Built: | 2026-05-07 07:07:10 UTC |
| Source: | https://github.com/cran/eegkit |
Creates two- or three-dimensional plot of electroencephalography (EEG) cap with user-input electrodes. Three-dimensional plots are created using the eegcoord data and the plot3d function (from rgl package). Currently supports 84 scalp electrodes, and plots according to the international 10-10 system. Includes customization options (e.g., each electrode can have a unique plotting color, size, label color, etc.).
eegcap(electrodes = "10-10", type = c("2d", "3d"), plotlabels = TRUE, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = NULL, col.point = NULL, col.border = NULL, cex.label = NULL, col.label = NULL, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", index = FALSE, plt = c(0.03,0.97,0.03,0.97), ...)eegcap(electrodes = "10-10", type = c("2d", "3d"), plotlabels = TRUE, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = NULL, col.point = NULL, col.border = NULL, cex.label = NULL, col.label = NULL, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", index = FALSE, plt = c(0.03,0.97,0.03,0.97), ...)
electrodes |
Character vector with electrodes to plot. Each element of |
type |
Type of plot to create: |
plotlabels |
If |
plotaxes |
If |
main |
Title to use for plot. Default is no title |
xyzlab |
Axis labels to use for plot. If |
cex.point |
Size of electrode points. Can have a unique size for each electrode. |
col.point |
Color of electrode points. Can have a unique color for each electrode. |
col.border |
Color of electrode point borders. Can have a unique color for each electrode. |
cex.label |
Size of electrode labels. Can have a unique size for each electrode label. Input is ignored if |
col.label |
Color of electrode labels. Can have a unique color for each electrode label. Input is ignored if |
nose |
If |
ears |
If |
head |
If |
col.head |
Color for dummy head in 3d plot. Ignored if |
index |
Logical indicating if the cap row indices should be returned (see Note). |
plt |
A vector of the form c(x1, x2, y1, y2) giving the coordinates of the plot region as fractions of the current figure region. See |
... |
Optional inputs for |
Produces plot of EEG cap and possibly returns cap row indices.
Currently supports 84 scalp electrodes (plus ears and nose): A1 A2 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AFZ C1 C2 C3 C4 C5 C6 CP1 CP2 CP3 CP4 CP5 CP6 CPZ CZ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 FC1 FC2 FC3 FC4 FC5 FC6 FCZ FP1 FP2 FPZ FT7 FT8 FT9 FT10 FZ I1 I2 IZ NZ O1 O2 OZ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 POZ PZ T7 T8 T9 T10 TP7 TP8 TP9 TP10
See eegcoord for the coordinates used to create plot. Setting index=TRUE returns the row indices of eegcoord that were used to plot the cap.
To save three-dimensional plots, use the rgl.postscript function (from rgl package).
Nathaniel E. Helwig <[email protected]>
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
########## EXAMPLE 1 ########## # plot 10-10 system (default): # plot full cap 2d (default options) eegcap() # plot full cap 2d (different color for ears and nose) data(eegcoord) mycols <- rep("white",87) enames <- rownames(eegcoord) mycols[enames=="A1"] <- "green" mycols[enames=="A2"] <- "light blue" mycols[enames=="NZ"] <- "pink" eegcap(col.point = mycols) ########## EXAMPLE 2 ########## # plot 10-20 system: # plot 2d cap with labels eegcap("10-20") # plot 2d cap without labels eegcap("10-20", plotlabels = FALSE) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcap(myelectrodes)########## EXAMPLE 1 ########## # plot 10-10 system (default): # plot full cap 2d (default options) eegcap() # plot full cap 2d (different color for ears and nose) data(eegcoord) mycols <- rep("white",87) enames <- rownames(eegcoord) mycols[enames=="A1"] <- "green" mycols[enames=="A2"] <- "light blue" mycols[enames=="NZ"] <- "pink" eegcap(col.point = mycols) ########## EXAMPLE 2 ########## # plot 10-20 system: # plot 2d cap with labels eegcap("10-20") # plot 2d cap without labels eegcap("10-20", plotlabels = FALSE) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcap(myelectrodes)
Creates two-dimensional plot of electroencephalography (EEG) cap with user-input electrodes. Currently supports 84 scalp electrodes, and plots according to the international 10-10 system. Includes customization options (e.g., each electrode can have a unique plotting color, size, label color, etc.).
eegcap2d(electrodes = "10-10", axes = FALSE, asp = 1, cex.point = 2.75, col.point = "green", pch.point = 19, cex.border = 2.75, col.border = "black", pch.border = 21, cex.label = 0.5, col.label = "black", head = TRUE, nose = TRUE, ears = TRUE, main = "", xlab = "", ylab = "", xlim = c(-13.7, 13.7), ylim = c(-13.7, 13.7), ...)eegcap2d(electrodes = "10-10", axes = FALSE, asp = 1, cex.point = 2.75, col.point = "green", pch.point = 19, cex.border = 2.75, col.border = "black", pch.border = 21, cex.label = 0.5, col.label = "black", head = TRUE, nose = TRUE, ears = TRUE, main = "", xlab = "", ylab = "", xlim = c(-13.7, 13.7), ylim = c(-13.7, 13.7), ...)
electrodes |
Character vector with electrodes to plot. Each element of |
axes |
If |
asp |
Aspect ratio for plot (defaults to 1). |
cex.point |
Character EXpansion value for electrodes. Set to a negative value to suppress the electrode plotting. |
col.point |
Color for electrodes. Ignored if |
pch.point |
Plotting character for electrodes. Ignored if |
cex.border |
Character EXpansion value for electrode borders. Set to a negative value to suppress the electrode border plotting. |
col.border |
Color for electrode borders. Ignored if |
pch.border |
Plotting character for electrode borders. Ignored if |
cex.label |
Character EXpansion value for electrode labels. Set to a negative value to suppress the electrode label plotting. |
col.label |
Color for electrode labels. Ignored if |
head |
If |
nose |
If |
ears |
If |
main |
Title to use for plot. Default is no title. |
xlab, ylab
|
x-axis and y-axis labels for the plot. Default is no axis labels. |
xlim, ylim
|
x-axis and y-axis limits for the plot. |
... |
Optional inputs for |
Currently supports 84 scalp electrodes (plus ears and nose): A1 A2 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AFZ C1 C2 C3 C4 C5 C6 CP1 CP2 CP3 CP4 CP5 CP6 CPZ CZ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 FC1 FC2 FC3 FC4 FC5 FC6 FCZ FP1 FP2 FPZ FT7 FT8 FT9 FT10 FZ I1 I2 IZ NZ O1 O2 OZ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 POZ PZ T7 T8 T9 T10 TP7 TP8 TP9 TP10
See eegcoord for the coordinates used to create plot.
Produces plot of EEG cap.
Unlike the eegcap function, this function does not use par$plt for the figure positioning.
Nathaniel E. Helwig <[email protected]>
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
See eegcap for a similar implementation, which also supports 3d EEG cap plotting.
########## EXAMPLE 1 ########## # plot 10-10 system (default): # plot full cap (default options) eegcap2d() # plot full cap (different color for ears and nose) data(eegcoord) mycols <- rep(NA, 87) enames <- rownames(eegcoord) mycols[enames=="A1"] <- "green" mycols[enames=="A2"] <- "light blue" mycols[enames=="NZ"] <- "pink" eegcap2d(col.point = mycols) ########## EXAMPLE 2 ########## # plot 10-20 system: # plot cap with labels eegcap2d("10-20") # plot cap without labels eegcap2d("10-20", cex.label = -1) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcap2d(myelectrodes)########## EXAMPLE 1 ########## # plot 10-10 system (default): # plot full cap (default options) eegcap2d() # plot full cap (different color for ears and nose) data(eegcoord) mycols <- rep(NA, 87) enames <- rownames(eegcoord) mycols[enames=="A1"] <- "green" mycols[enames=="A2"] <- "light blue" mycols[enames=="NZ"] <- "pink" eegcap2d(col.point = mycols) ########## EXAMPLE 2 ########## # plot 10-20 system: # plot cap with labels eegcap2d("10-20") # plot cap without labels eegcap2d("10-20", cex.label = -1) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcap2d(myelectrodes)
Creates two- or three-dimensional plot of dense electroencephalography (EEG) cap that spans user-input electrodes. Three-dimensional plots are created using the eegdense data and the plot3d function (from rgl package). Currently supports 933 scalp electrodes. Includes customization options (e.g., each electrode can have a unique plotting color, size, label color, etc.).
eegcapdense(electrodes = "10-10", type = c("2d", "3d"), plotlabels = TRUE, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = NULL, col.point = NULL, cex.label = NULL, col.label = NULL, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", index = FALSE, zconst = 0.5, plt = c(0.03,0.97,0.03,0.97), ...)eegcapdense(electrodes = "10-10", type = c("2d", "3d"), plotlabels = TRUE, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = NULL, col.point = NULL, cex.label = NULL, col.label = NULL, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", index = FALSE, zconst = 0.5, plt = c(0.03,0.97,0.03,0.97), ...)
electrodes |
Character vector with electrodes to plot. Each element of |
type |
Type of plot to create: |
plotlabels |
If |
plotaxes |
If |
main |
Title to use for plot. Default is no title |
xyzlab |
Axis labels to use for plot. If |
cex.point |
Size of electrode points. Can have a unique size for each electrode. |
col.point |
Color of electrode points. Can have a unique color for each electrode. |
cex.label |
Size of electrode labels. Can have a unique size for each electrode label. Input is ignored if |
col.label |
Color of electrode labels. Can have a unique color for each electrode label. Input is ignored if |
nose |
If |
ears |
If |
head |
If |
col.head |
Color for dummy head in 3d plot. Ignored if |
index |
Logical indicating if the cap row indices should be returned (see Note). |
zconst |
Scalar controlling which row indices should be returned (see Note). |
plt |
A vector of the form c(x1, x2, y1, y2) giving the coordinates of the plot region as fractions of the current figure region. See |
... |
Optional inputs for |
Produces plot of EEG cap and possibly returns cap row indices.
Currently supports 84 scalp electrodes (plus ears and nose): A1 A2 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AFZ C1 C2 C3 C4 C5 C6 CP1 CP2 CP3 CP4 CP5 CP6 CPZ CZ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 FC1 FC2 FC3 FC4 FC5 FC6 FCZ FP1 FP2 FPZ FT7 FT8 FT9 FT10 FZ I1 I2 IZ NZ O1 O2 OZ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 POZ PZ T7 T8 T9 T10 TP7 TP8 TP9 TP10
See eegdense for the coordinates used to create plot. Setting index=TRUE returns the row indices of eegdense that were used to plot the cap. Only returns row indices with z-coordinates >= (zmin-zconst), where zmin is minimum z-coordinate of input electrodes.
To save three-dimensional plots, use the rgl.postscript function (from rgl package).
Nathaniel E. Helwig <[email protected]>
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
########## EXAMPLE 1 ########## # plot 10-10 system (default): eegcapdense() ########## EXAMPLE 2 ########## # plot 10-20 system: eegcapdense("10-20", plotlabels = FALSE) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcapdense(myelectrodes)########## EXAMPLE 1 ########## # plot 10-10 system (default): eegcapdense() ########## EXAMPLE 2 ########## # plot 10-20 system: eegcapdense("10-20", plotlabels = FALSE) ########## EXAMPLE 3 ########## # plot custom subset of electrodes myelectrodes <- c("FP1","FP2","FPZ","F7","F3","FZ", "F4","F8","T7","C3","CZ","C4","T8", "P7","P3","PZ","P4","P8","O1","O2") eegcapdense(myelectrodes)
Three-dimensional electroencephalography (EEG) electrode coordinates (measured in cm), and corresponding projection onto two-dimensional xy plane. Contains 84 scalp electrodes, as well as nose and ears.
data(eegcoord)data(eegcoord)
A data frame with 87 observations and the following 5 variables:
x-coordinate of 3d cap (numeric).
y-coordinate of 3d cap (numeric).
z-coordinate of 3d cap (numeric).
Projected x-coordinate of 2d cap (numeric).
Projected y-coordinate of 2d cap (numeric).
Electrode channel name labels can be obtained using rownames(eegcoord).
Nathaniel E. Helwig <[email protected]>
Created by Nathaniel E. Helwig (2014) using:
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
Schlager S (2017). Morpho and Rvcg - Shape Analysis in R. In Zheng G, Li S, Szekely G (eds.), Statistical Shape and Deformation Analysis, 217-256. Academic Press. ISBN 9780128104934.
########## EXAMPLE ########## data(eegcoord) enames <- rownames(eegcoord) # plot3d(eegcoord[,1],eegcoord[,2],eegcoord[,3],size=10,col="green") # text3d(eegcoord[,1],eegcoord[,2],eegcoord[,3],texts=enames,col="blue") plot(eegcoord[,4],eegcoord[,5],cex=2,col="green",pch=19) text(eegcoord[,4],eegcoord[,5],labels=enames,col="blue")########## EXAMPLE ########## data(eegcoord) enames <- rownames(eegcoord) # plot3d(eegcoord[,1],eegcoord[,2],eegcoord[,3],size=10,col="green") # text3d(eegcoord[,1],eegcoord[,2],eegcoord[,3],texts=enames,col="blue") plot(eegcoord[,4],eegcoord[,5],cex=2,col="green",pch=19) text(eegcoord[,4],eegcoord[,5],labels=enames,col="blue")
Dense (hypothetical) three-dimensional electroencephalography (EEG) electrode coordinates, and corresponding projection onto two-dimensional plane. Dense cap spans the 84 scalp electrodes defined in eegcoord.
data(eegdense)data(eegdense)
A data frame with 977 observations and the following 5 variables:
x-coordinate of 3d cap (numeric).
y-coordinate of 3d cap (numeric).
z-coordinate of 3d cap (numeric).
Projected x-coordinate of 2d cap (numeric).
Projected y-coordinate of 2d cap (numeric).
Nathaniel E. Helwig <[email protected]>
Created by Nathaniel E. Helwig (2014) using:
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
Schlager S (2017). Morpho and Rvcg - Shape Analysis in R. In Zheng G, Li S, Szekely G (eds.), Statistical Shape and Deformation Analysis, 217-256. Academic Press. ISBN 9780128104934.
########## EXAMPLE ########## data(eegdense) # plot3d(eegdense[,1],eegdense[,2],eegdense[,3],size=10,col="green") plot(eegdense[,4],eegdense[,5],cex=1,col="green",pch=19)########## EXAMPLE ########## data(eegdense) # plot3d(eegdense[,1],eegdense[,2],eegdense[,3],size=10,col="green") plot(eegdense[,4],eegdense[,5],cex=1,col="green",pch=19)
Finds the strength (amplitude) and phase shift of the input signal(s) at a particular range of frequencies via a Discrete Fast Fourier Transform (FFT). Can input single or multi-channel data.
eegfft(x, Fs, lower, upper)eegfft(x, Fs, lower, upper)
x |
Vector or matrix (time by channel) of EEG data with |
Fs |
Sampling rate of |
lower |
Lower band in Hz. Smallest frequency to keep (defaults to |
upper |
Upper band in Hz. Largest frequency to keep (defaults to |
The fft function (or mvfft function) is used to implement the FFT (or multivatiate FFT). Given the FFT, the strength of the signal is the modulus (Mod), and the phase.shift is the angle (Arg).
If x is a vector, returns a data frame with variables:
frequency |
vector of frequencies |
strength |
strength (amplitude) of signal at each frequency |
phase.shift |
phase shift of signal at each frequency |
If x is a matrix with J channels, returns a list with elements:
frequency |
vector of frequencies of length |
strength |
|
phase.shift |
|
The strength of the signal has the same unit as the input (typically microvolts), and the phase shift is measured in radians (range - to ).
Nathaniel E. Helwig <[email protected]>
Cooley, James W., and Tukey, John W. (1965) An algorithm for the machine calculation of complex Fourier series, Math. Comput. 19(90), 297-301. doi:10.7551/mitpress/5222.003.0014
Singleton, R. C. (1979) Mixed Radix Fast Fourier Transforms, in Programs for Digital Signal Processing, IEEE Digital Signal Processing Committee eds. IEEE Press.
########## EXAMPLE ########## ### Data Generation ### # parameters for signal Fs <- 1000 # 1000 Hz signal s <- 3 # 3 seconds of data t <- seq(0, s - 1/Fs, by = 1/Fs) # time sequence n <- length(t) # number of data points freqs <- c(1, 5, 10, 20) # frequencies amp <- c(2, 1.5, 3, 1.75) # strengths (amplitudes) phs <- c(0, pi/6, pi/4, pi/2) # phase shifts # create data generating signals mu <- rep(0, n) for(j in 1:length(freqs)){ mu <- mu + amp[j] * sin(2*pi*t*freqs[j] + phs[j]) } set.seed(1) # set random seed e <- rnorm(n) # Gaussian error y <- mu + e # data = mean + error ### FFT of Noise-Free Data ### # fft of noise-free data ef <- eegfft(mu, Fs = Fs, upper = 40) head(ef) ef[ef$strength > 0.25,] # plot frequency strength par(mfrow = c(1,2)) plot(x = ef$frequency, y = ef$strength, t = "b", xlab = "Frequency (Hz)", ylab = expression("Strength (" * mu * "V)"), main = "FFT of Noise-Free Data") # compare to data generating parameters cbind(amp, ef$strength[ef$strength > 0.25]) cbind(phs - pi/2, ef$phase[ef$strength > 0.25]) ### FFT of Noisy Data ### # fft of noisy data ef <- eegfft(y, Fs = Fs, upper = 40) head(ef) ef[ef$strength > 0.25,] # plot frequency strength plot(x = ef$frequency, y = ef$strength, t = "b", xlab = "Frequency (Hz)", ylab = expression("Strength (" * mu * "V)"), main = "FFT of Noisy Data") # compare to data generating parameters cbind(amp, ef$strength[ef$strength > 0.25]) cbind(phs - pi/2, ef$phase[ef$strength > 0.25])########## EXAMPLE ########## ### Data Generation ### # parameters for signal Fs <- 1000 # 1000 Hz signal s <- 3 # 3 seconds of data t <- seq(0, s - 1/Fs, by = 1/Fs) # time sequence n <- length(t) # number of data points freqs <- c(1, 5, 10, 20) # frequencies amp <- c(2, 1.5, 3, 1.75) # strengths (amplitudes) phs <- c(0, pi/6, pi/4, pi/2) # phase shifts # create data generating signals mu <- rep(0, n) for(j in 1:length(freqs)){ mu <- mu + amp[j] * sin(2*pi*t*freqs[j] + phs[j]) } set.seed(1) # set random seed e <- rnorm(n) # Gaussian error y <- mu + e # data = mean + error ### FFT of Noise-Free Data ### # fft of noise-free data ef <- eegfft(mu, Fs = Fs, upper = 40) head(ef) ef[ef$strength > 0.25,] # plot frequency strength par(mfrow = c(1,2)) plot(x = ef$frequency, y = ef$strength, t = "b", xlab = "Frequency (Hz)", ylab = expression("Strength (" * mu * "V)"), main = "FFT of Noise-Free Data") # compare to data generating parameters cbind(amp, ef$strength[ef$strength > 0.25]) cbind(phs - pi/2, ef$phase[ef$strength > 0.25]) ### FFT of Noisy Data ### # fft of noisy data ef <- eegfft(y, Fs = Fs, upper = 40) head(ef) ef[ef$strength > 0.25,] # plot frequency strength plot(x = ef$frequency, y = ef$strength, t = "b", xlab = "Frequency (Hz)", ylab = expression("Strength (" * mu * "V)"), main = "FFT of Noisy Data") # compare to data generating parameters cbind(amp, ef$strength[ef$strength > 0.25]) cbind(phs - pi/2, ef$phase[ef$strength > 0.25])
Low-pass, high-pass, or band-pass filter EEG data using either a Butterworth filter (default) or a finite impulse response (FIR) filter.
eegfilter(x, Fs, lower, upper, method = "butter", order = 3L, forwardreverse = TRUE, scale = FALSE, plot = FALSE)eegfilter(x, Fs, lower, upper, method = "butter", order = 3L, forwardreverse = TRUE, scale = FALSE, plot = FALSE)
x |
Vector or matrix (time by channel) of EEG data with |
Fs |
Sampling rate of |
lower |
Lower band in Hz. Smallest frequency to keep. |
upper |
Upper band in Hz. Largest frequency to keep. |
method |
Filtering method. Either |
order |
Order of the filter. See corresponding argument of |
forwardreverse |
If |
scale |
If |
plot |
If |
For a low-pass filter, only enter the upper frequency to keep. For a high-pass filter, only enter the lower frequency to keep. For a band-pass filter, enter both the lower and upper frequency bounds.
Filtered version of input data.
Nathaniel E. Helwig <[email protected]>
http://en.wikipedia.org/wiki/Butterworth_filter
http://en.wikipedia.org/wiki/Fir_filter
filter, filtfilt, butter, fir1
########## EXAMPLE ########## # create data generating signals n <- 1000 # 1000 Hz signal s <- 2 # 2 seconds of data t <- seq(0, s, length.out = s * n) # time vector s1 <- sin(2*pi*t) # 1 Hz sinusoid s5 <- sin(2*pi*t*5) # 5 Hz sinusoid s10 <- sin(2*pi*t*10) # 10 Hz sinusoid s20 <- sin(2*pi*t*20) # 20 Hz sinusoid # create data set.seed(1) # set random seed e <- rnorm(s * n, sd = 0.25) # Gaussian error mu <- s1 + s5 + s10 + s20 # 1 + 5 + 10 + 20 Hz mean y <- mu + e # data = mean + error # 4-th order Butterworth filter (2 to 15 Hz band-pass) yf.but <- eegfilter(y, Fs = n, lower = 2, upper = 15, method = "butter", order = 4) # 350-th order FIR filter (2 to 15 Hz band-pass) yf.fir <- eegfilter(y, Fs = n, lower = 2, upper = 15, method = "fir1", order = 350) # check quality of results yftrue <- s5 + s10 # true (filtered) mean signal mean((yf.but - yftrue)^2) # mse between yf.but and yftrue mean((yf.fir - yftrue)^2) # mse between yf.fir and yftrue # plot true and estimated filtered signals plot(t, yftrue, type = "l", lty = 1, lwd = 2, ylim = c(-3, 3)) lines(t, yf.but, col = "blue", lty = 2, lwd = 2) lines(t, yf.fir, col = "red", lty = 3, lwd = 2) legend("topright", legend = c("Truth", "Butterworth", "FIR"), lty = 1:3, lwd = 2, col = c("black", "blue", "red"), bty = "n") # power spectral density before and after filtering (dB) par(mfrow=c(1,3), mar = c(5, 4.5, 4, 2) + 0.1) eegpsd(y, Fs = n, upper = 50, t = "b", main = "Before Filtering", lwd = 2) rect(2, -63, 15, 1, col = rgb(0.5,0.5,0.5,1/4)) legend("topright", legend = "2-15 Hz Filter", fill = rgb(0.5,0.5,0.5,1/4), bty = "n") eegpsd(yf.but, Fs = n, upper = 50, t = "b", main = "After Butterworth Filter", lwd = 2) eegpsd(yf.fir, Fs = n, upper = 50, t = "b", main = "After FIR Filter", lwd = 2) # power spectral density before and after filtering (mv^2) par(mfrow=c(1,3), mar = c(5, 4.5, 4, 2) + 0.1) eegpsd(y, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "Before Filtering", lwd = 2) rect(2, 0, 15, 1.05, col = rgb(0.5,0.5,0.5,1/4)) legend("topright", legend = "2-15 Hz Filter", fill = rgb(0.5,0.5,0.5,1/4), bty = "n") eegpsd(yf.but, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "After Butterworth Filter", lwd = 2) eegpsd(yf.fir, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "After FIR Filter", lwd = 2)########## EXAMPLE ########## # create data generating signals n <- 1000 # 1000 Hz signal s <- 2 # 2 seconds of data t <- seq(0, s, length.out = s * n) # time vector s1 <- sin(2*pi*t) # 1 Hz sinusoid s5 <- sin(2*pi*t*5) # 5 Hz sinusoid s10 <- sin(2*pi*t*10) # 10 Hz sinusoid s20 <- sin(2*pi*t*20) # 20 Hz sinusoid # create data set.seed(1) # set random seed e <- rnorm(s * n, sd = 0.25) # Gaussian error mu <- s1 + s5 + s10 + s20 # 1 + 5 + 10 + 20 Hz mean y <- mu + e # data = mean + error # 4-th order Butterworth filter (2 to 15 Hz band-pass) yf.but <- eegfilter(y, Fs = n, lower = 2, upper = 15, method = "butter", order = 4) # 350-th order FIR filter (2 to 15 Hz band-pass) yf.fir <- eegfilter(y, Fs = n, lower = 2, upper = 15, method = "fir1", order = 350) # check quality of results yftrue <- s5 + s10 # true (filtered) mean signal mean((yf.but - yftrue)^2) # mse between yf.but and yftrue mean((yf.fir - yftrue)^2) # mse between yf.fir and yftrue # plot true and estimated filtered signals plot(t, yftrue, type = "l", lty = 1, lwd = 2, ylim = c(-3, 3)) lines(t, yf.but, col = "blue", lty = 2, lwd = 2) lines(t, yf.fir, col = "red", lty = 3, lwd = 2) legend("topright", legend = c("Truth", "Butterworth", "FIR"), lty = 1:3, lwd = 2, col = c("black", "blue", "red"), bty = "n") # power spectral density before and after filtering (dB) par(mfrow=c(1,3), mar = c(5, 4.5, 4, 2) + 0.1) eegpsd(y, Fs = n, upper = 50, t = "b", main = "Before Filtering", lwd = 2) rect(2, -63, 15, 1, col = rgb(0.5,0.5,0.5,1/4)) legend("topright", legend = "2-15 Hz Filter", fill = rgb(0.5,0.5,0.5,1/4), bty = "n") eegpsd(yf.but, Fs = n, upper = 50, t = "b", main = "After Butterworth Filter", lwd = 2) eegpsd(yf.fir, Fs = n, upper = 50, t = "b", main = "After FIR Filter", lwd = 2) # power spectral density before and after filtering (mv^2) par(mfrow=c(1,3), mar = c(5, 4.5, 4, 2) + 0.1) eegpsd(y, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "Before Filtering", lwd = 2) rect(2, 0, 15, 1.05, col = rgb(0.5,0.5,0.5,1/4)) legend("topright", legend = "2-15 Hz Filter", fill = rgb(0.5,0.5,0.5,1/4), bty = "n") eegpsd(yf.but, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "After Butterworth Filter", lwd = 2) eegpsd(yf.fir, Fs = n, upper = 50, unit = "mV^2", t = "b", main = "After FIR Filter", lwd = 2)
Contains mesh3d object of dummy head, which is used in the plotting functions eegcap and eegspace. This is a transformed (translated, rotated, and rescaled) vesion of the dummyhead object from the Rvcg package.
data(eeghead)data(eeghead)
mesh3d object
Nathaniel E. Helwig <[email protected]>
Created by Nathaniel E. Helwig (2014) using:
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Schlager S (2017). Morpho and Rvcg - Shape Analysis in R. In Zheng G, Li S, Szekely G (eds.), Statistical Shape and Deformation Analysis, 217-256. Academic Press. ISBN 9780128104934.
########## EXAMPLE ########## # data(eeghead) # shade3d(eeghead) # eeghead$material$color <- rep("black",length(eeghead$material$color)) # wire3d(eeghead)########## EXAMPLE ########## # data(eeghead) # shade3d(eeghead) # eeghead$material$color <- rep("black",length(eeghead$material$color)) # wire3d(eeghead)
Computes temporal (default) or spatial ICA decomposition of EEG data. Can use Infomax (default), FastICA, or JADE algorithm. ICA computations are conducted via icaimax, icafast, or icajade from the ica package.
eegica(X, nc, center = TRUE, maxit = 100, tol = 1e-6, Rmat = diag(nc), type = c("time", "space"), method = c("imax", "fast", "jade"), ...)eegica(X, nc, center = TRUE, maxit = 100, tol = 1e-6, Rmat = diag(nc), type = c("time", "space"), method = c("imax", "fast", "jade"), ...)
X |
Data matrix with |
nc |
Number of components to extract. |
center |
If |
maxit |
Maximum number of algorithm iterations to allow. |
tol |
Convergence tolerance. |
Rmat |
Initial estimate of the |
type |
Type of ICA decomposition: |
method |
Method for ICA decomposition: |
... |
ICA Model
The ICA model can be written as X = tcrossprod(S, M) + E, where columns of S contain the source signals, M is the mixing matrix, and columns of E contain the noise signals. Columns of X are assumed to have zero mean. The goal is to find the unmixing matrix W such that columns of S = tcrossprod(X, W) are independent as possible.
Whitening
Without loss of generality, we can write M = P %*% R where P is a tall matrix and R is an orthogonal rotation matrix. Letting Q denote the pseudoinverse of P, we can whiten the data using Y = tcrossprod(X,Q). The goal is to find the orthongal rotation matrix R such that the source signal estimates S = Y %*% R are as independent as possible. Note that W = crossprod(R,Q).
Infomax
The Infomax approach finds the orthogonal rotation matrix R that (approximately) maximizes the joint entropy of a nonlinear function of the estimated source signals. See Bell and Sejnowski (1995) and Helwig (in prep) for specifics of algorithms.
FastICA
The FastICA algorithm finds the orthogonal rotation matrix R that (approximately) maximizes the negentropy of the estimated source signals. Negentropy is approximated using
where E denotes the expectation, G is the contrast function, and z is a standard normal variable. See Hyvarinen (1999) for specifics of fixed-point algorithm.
JADE
The JADE approach finds the orthogonal rotation matrix R that (approximately) diagonalizes the cumulant array of the source signals. See Cardoso and Souloumiac (1993,1996) and Helwig and Hong (2013) for specifics of the JADE algorithm.
S |
Matrix of source signal estimates ( |
M |
Estimated mixing matrix. |
W |
Estimated unmixing matrix ( |
Y |
Whitened data matrix. |
Q |
Whitening matrix. |
R |
Orthogonal rotation matrix. |
vafs |
Variance-accounted-for by each component. |
iter |
Number of algorithm iterations. |
type |
ICA type (same as input). |
method |
ICA method (same as input). |
If type="time", the data matrix is transposed before calling ICA algorithm (i.e., X = t(X)), and the columns of the tranposed data matrix are centered.
Nathaniel E. Helwig <[email protected]>
Bell, A.J. & Sejnowski, T.J. (1995). An information-maximization approach to blind separation and blind deconvolution. Neural Computation, 7, 1129-1159. doi:10.1162/neco.1995.7.6.1129
Cardoso, J.F., & Souloumiac, A. (1993). Blind beamforming for non-Gaussian signals. IEE Proceedings-F, 140, 362-370. doi:10.1049/ip-f-2.1993.0054
Cardoso, J.F., & Souloumiac, A. (1996). Jacobi angles for simultaneous diagonalization. SIAM Journal on Matrix Analysis and Applications, 17, 161-164. doi:10.1137/S0895479893259546
Helwig, N.E. (2022). ica: Independent Component Analysis, doi:10.32614/CRAN.package.ica, R package version 1.0-3. http://CRAN.R-project.org/package=ica
Helwig, N.E. & Hong, S. (2013). A critique of Tensor Probabilistic Independent Component Analysis: Implications and recommendations for multi-subject fMRI data analysis. Journal of Neuroscience Methods, 213, 263-273. doi:10.1016/j.jneumeth.2012.12.009
Hyvarinen, A. (1999). Fast and robust fixed-point algorithms for independent component analysis. IEEE Transactions on Neural Networks, 10, 626-634. doi:10.1109/72.761722
########## EXAMPLE ########## # get "c" subjects of "eegdata" data data(eegdata) idx <- which(eegdata$group=="c") eegdata <- eegdata[idx,] # get average data (across subjects) eegmean <- tapply(eegdata$voltage,list(eegdata$channel,eegdata$time),mean) # remove ears and nose acnames <- rownames(eegmean) idx <- c(which(acnames=="X"),which(acnames=="Y"),which(acnames=="nd")) eegmean <- eegmean[-idx,] # get spatial coordinates (for plotting) data(eegcoord) cidx <- match(rownames(eegmean),rownames(eegcoord)) # temporal ICA with 4 components icatime <- eegica(eegmean,4) icatime$vafs # quartz() # par(mfrow=c(4,2)) # tseq <- (0:255)*1000/255 # for(j in 1:4){ # par(mar=c(5.1,4.6,4.1,2.1)) # sptitle <- bquote("VAF: "*.(round(icatime$vafs[j],4))) # eegtime(tseq,icatime$S[,j],main=bquote("Component "*.(j)),cex.main=1.5) # eegspace(eegcoord[cidx,4:5],icatime$M[,j],main=sptitle) # } # spatial ICA with 4 components icaspace <- eegica(eegmean,4,type="space") icaspace$vafs # quartz() # par(mfrow=c(4,2)) # tseq <- (0:255)*1000/255 # for(j in 1:4){ # par(mar=c(5.1,4.6,4.1,2.1)) # sptitle <- bquote("VAF: "*.(round(icaspace$vafs[j],4))) # eegtime(tseq,icaspace$M[,j],main=bquote("Component "*.(j)),cex.main=1.5) # eegspace(eegcoord[cidx,4:5],icaspace$S[,j],main=sptitle) # }########## EXAMPLE ########## # get "c" subjects of "eegdata" data data(eegdata) idx <- which(eegdata$group=="c") eegdata <- eegdata[idx,] # get average data (across subjects) eegmean <- tapply(eegdata$voltage,list(eegdata$channel,eegdata$time),mean) # remove ears and nose acnames <- rownames(eegmean) idx <- c(which(acnames=="X"),which(acnames=="Y"),which(acnames=="nd")) eegmean <- eegmean[-idx,] # get spatial coordinates (for plotting) data(eegcoord) cidx <- match(rownames(eegmean),rownames(eegcoord)) # temporal ICA with 4 components icatime <- eegica(eegmean,4) icatime$vafs # quartz() # par(mfrow=c(4,2)) # tseq <- (0:255)*1000/255 # for(j in 1:4){ # par(mar=c(5.1,4.6,4.1,2.1)) # sptitle <- bquote("VAF: "*.(round(icatime$vafs[j],4))) # eegtime(tseq,icatime$S[,j],main=bquote("Component "*.(j)),cex.main=1.5) # eegspace(eegcoord[cidx,4:5],icatime$M[,j],main=sptitle) # } # spatial ICA with 4 components icaspace <- eegica(eegmean,4,type="space") icaspace$vafs # quartz() # par(mfrow=c(4,2)) # tseq <- (0:255)*1000/255 # for(j in 1:4){ # par(mar=c(5.1,4.6,4.1,2.1)) # sptitle <- bquote("VAF: "*.(round(icaspace$vafs[j],4))) # eegtime(tseq,icaspace$M[,j],main=bquote("Component "*.(j)),cex.main=1.5) # eegspace(eegcoord[cidx,4:5],icaspace$S[,j],main=sptitle) # }
Contains mesh3d object of eegdense, which is used in the plotting function eegspace.
data(eegmesh)data(eegmesh)
mesh3d object
Nathaniel E. Helwig <[email protected]>
Created by Nathaniel E. Helwig (2014) using:
Murdoch, D., and Adler, D. (2025). rgl: 3D Visualization Using OpenGL. doi:10.32614/CRAN.package.rgl, R package version 1.3.18, http://CRAN.R-project.org/package=rgl
Oostenveld, R., and Praamstra, P. (2001). The Five percent electrode system for high-resolution EEG and ERP measurements. Clinical Neurophysiology, 112, 713-719. doi:10.1016/S1388-2457(00)00527-7
Schlager S (2017). Morpho and Rvcg - Shape Analysis in R. In Zheng G, Li S, Szekely G (eds.), Statistical Shape and Deformation Analysis, 217-256. Academic Press. ISBN 9780128104934.
########## EXAMPLE ########## # data(eegmesh) # wire3d(eegmesh) # eegmesh$material$color <- rep("red",length(eegmesh$material$color)) # shade3d(eegmesh)########## EXAMPLE ########## # data(eegmesh) # wire3d(eegmesh) # eegmesh$material$color <- rep("red",length(eegmesh$material$color)) # shade3d(eegmesh)
Uses a fast discrete Fourier transform (eegfft) to estimate the power spectral density of EEG data, and plots the power esimate using the plot (single channel) or imagebar (multi-channel) function.
eegpsd(x, Fs, lower, upper, units = "dB", xlab = NULL, ylab = NULL, zlab = NULL, ...)eegpsd(x, Fs, lower, upper, units = "dB", xlab = NULL, ylab = NULL, zlab = NULL, ...)
x |
Vector or matrix (time by channel) of EEG data with |
Fs |
Sampling rate of |
lower |
Lower band in Hz. Smallest frequency to keep. |
upper |
Upper band in Hz. Largest frequency to keep. |
units |
Units for plot. Options include "dB" for decibals (default), "mV" for microvolts, and "mV^2" for squared microvolts. Note dB = 10*log10(mV^2). |
xlab |
x-axis label for the plot/image. |
ylab |
y-axis label for the plot/image. |
zlab |
z-axis label for the plot/image. |
... |
Produces a plot (single channel) or image (multi-channel).
Nathaniel E. Helwig <[email protected]>
Cooley, James W., and Tukey, John W. (1965) An algorithm for the machine calculation of complex Fourier series, Math. Comput. 19(90), 297-301.
Singleton, R. C. (1979) Mixed Radix Fast Fourier Transforms, in Programs for Digital Signal Processing, IEEE Digital Signal Processing Committee eds. IEEE Press.
########## EXAMPLE ########## # create data generating signals n <- 1000 # 1000 Hz signal s <- 2 # 2 seconds of data t <- seq(0, s, length.out = s * n) # time vector s1 <- sin(2*pi*t) # 1 Hz sinusoid s5 <- sin(2*pi*t*5) # 5 Hz sinusoid s10 <- sin(2*pi*t*10) # 10 Hz sinusoid s20 <- sin(2*pi*t*20) # 20 Hz sinusoid # create data set.seed(1) # set random seed e <- rnorm(s * n, sd = 0.25) # Gaussian error mu <- s1 + s5 + s10 + s20 # 1 + 5 + 10 + 20 Hz mean y <- mu + e # data = mean + error # plot psd (single channel) eegpsd(y, Fs = n, upper = 30, t = "b") # plot psd (multi-channel) ym <- cbind(s1, s5, s10, s20) eegpsd(ym, Fs = n, upper = 30, units = "mV")########## EXAMPLE ########## # create data generating signals n <- 1000 # 1000 Hz signal s <- 2 # 2 seconds of data t <- seq(0, s, length.out = s * n) # time vector s1 <- sin(2*pi*t) # 1 Hz sinusoid s5 <- sin(2*pi*t*5) # 5 Hz sinusoid s10 <- sin(2*pi*t*10) # 10 Hz sinusoid s20 <- sin(2*pi*t*20) # 20 Hz sinusoid # create data set.seed(1) # set random seed e <- rnorm(s * n, sd = 0.25) # Gaussian error mu <- s1 + s5 + s10 + s20 # 1 + 5 + 10 + 20 Hz mean y <- mu + e # data = mean + error # plot psd (single channel) eegpsd(y, Fs = n, upper = 30, t = "b") # plot psd (multi-channel) ym <- cbind(s1, s5, s10, s20) eegpsd(ym, Fs = n, upper = 30, units = "mV")
Turn a signal of length N into a signal of length n via linear interpolation.
eegresample(x, n)eegresample(x, n)
x |
Vector or matrix (time by channel) of EEG data with |
n |
Number of time points for the resampled data. |
Data are resampled using the "Linear Length Normalization" approach described in Helwig et al. (2011). Let denote the input vector of length , and define a vector with entries
for where . The resampled vector is calculated as
for where and denote the floor and ceiling functions.
Resampled version of input data with n time points.
Typical usage is to down-sample (i.e., decrease the sampling rate of) a signal: n < N.
Nathaniel E. Helwig <[email protected]>
Helwig, N. E., Hong, S., Hsiao-Wecksler E. T., & Polk, J. D. (2011). Methods to temporally align gait cycle data. Journal of Biomechanics, 44(3), 561-566. doi:10.1016/j.jbiomech.2010.09.015
########## EXAMPLE 1 ########## # create vector with N = 200 time points N <- 200 x <- sin(4 * pi * seq(0, 1, length.out = N)) # down-sample (i.e., decrease sampling rate) to n = 100 y <- eegresample(x, n = 100) mean((y - sin(4 * pi * seq(0, 1, length.out = 100)))^2) # up-sample (i.e., increase sampling rate) to n = 500 z <- eegresample(x, n = 500) mean((z - sin(4 * pi * seq(0, 1, length.out = 500)))^2) # plot results par(mfrow = c(1,3)) plot(x, main = "Original (N = 200)") plot(y, main = "Down-sampled (n = 100)") plot(z, main = "Up-sampled (n = 500)") ########## EXAMPLE 2 ########## # create matrix with N = 500 time points and 2 columns N <- 500 x <- cbind(sin(2 * pi * seq(0, 1, length.out = N)), sin(4 * pi * seq(0, 1, length.out = N))) # down-sample (i.e., decrease sampling rate) to n = 250 y <- eegresample(x, n = 250) ytrue <- cbind(sin(2 * pi * seq(0, 1, length.out = 250)), sin(4 * pi * seq(0, 1, length.out = 250))) mean((y - ytrue)^2) # up-sample (i.e., increase sampling rate) to n = 1000 z <- eegresample(x, n = 1000) ztrue <- cbind(sin(2 * pi * seq(0, 1, length.out = 1000)), sin(4 * pi * seq(0, 1, length.out = 1000))) mean((z - ztrue)^2) # plot results par(mfrow = c(1,3)) plot(x[,1], main = "Original (N = 500)", cex = 0.5) points(x[,2], pch = 2, col = "blue", cex = 0.5) plot(y[,1], main = "Down-sampled (n = 250)", cex = 0.5) points(y[,2], pch = 2, col = "blue", cex = 0.5) plot(z[,1], main = "Up-sampled (n = 1000)", cex = 0.5) points(z[,2], pch = 2, col = "blue", cex = 0.5)########## EXAMPLE 1 ########## # create vector with N = 200 time points N <- 200 x <- sin(4 * pi * seq(0, 1, length.out = N)) # down-sample (i.e., decrease sampling rate) to n = 100 y <- eegresample(x, n = 100) mean((y - sin(4 * pi * seq(0, 1, length.out = 100)))^2) # up-sample (i.e., increase sampling rate) to n = 500 z <- eegresample(x, n = 500) mean((z - sin(4 * pi * seq(0, 1, length.out = 500)))^2) # plot results par(mfrow = c(1,3)) plot(x, main = "Original (N = 200)") plot(y, main = "Down-sampled (n = 100)") plot(z, main = "Up-sampled (n = 500)") ########## EXAMPLE 2 ########## # create matrix with N = 500 time points and 2 columns N <- 500 x <- cbind(sin(2 * pi * seq(0, 1, length.out = N)), sin(4 * pi * seq(0, 1, length.out = N))) # down-sample (i.e., decrease sampling rate) to n = 250 y <- eegresample(x, n = 250) ytrue <- cbind(sin(2 * pi * seq(0, 1, length.out = 250)), sin(4 * pi * seq(0, 1, length.out = 250))) mean((y - ytrue)^2) # up-sample (i.e., increase sampling rate) to n = 1000 z <- eegresample(x, n = 1000) ztrue <- cbind(sin(2 * pi * seq(0, 1, length.out = 1000)), sin(4 * pi * seq(0, 1, length.out = 1000))) mean((z - ztrue)^2) # plot results par(mfrow = c(1,3)) plot(x[,1], main = "Original (N = 500)", cex = 0.5) points(x[,2], pch = 2, col = "blue", cex = 0.5) plot(y[,1], main = "Down-sampled (n = 250)", cex = 0.5) points(y[,2], pch = 2, col = "blue", cex = 0.5) plot(z[,1], main = "Up-sampled (n = 1000)", cex = 0.5) points(z[,2], pch = 2, col = "blue", cex = 0.5)
Simulates event-related potential EEG data from hypothetical visual-stimulus ERP study. Data are simulated using a linear combination of five spatiotemporal component functions: P100, N100, P200, N200, and P300 components. User can control the coefficient (weight) given to each component, as well as the time shift (delay) of each component.
eegsim(channel, time, coefs = rep(1,5), tshift = rep(0,5))eegsim(channel, time, coefs = rep(1,5), tshift = rep(0,5))
channel |
Character vector of length |
time |
Numeric vector of length |
coefs |
Numeric vector of length 5 giving the coefficients (weights) to use for P100, N100, P200, N200, and P300 components (respectively). |
tshift |
Numeric vector of length 5 giving the time shifts (delays) to use for P100, N100, P200, N200, and P300 components (respectively). |
Returns a vector of simulated EEG data corresponding to the input channel(s), time point(s), coefficients, and time shifts.
Simulates data for 39 parietal and occipital electrodes: CP1 CP2 CP3 CP4 CP5 CP6 CPZ I1 I2 IZ O1 O2 OZ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 POZ PZ TP7 TP8 TP9 TP10
Returns simulated value of 0 for other electrodes.
Nathaniel E. Helwig <[email protected]>
Created by Nathaniel E. Helwig (2014) using data from:
Begleiter, H. (1995). EEG Database [Dataset]. UCI Machine Learning Repository. doi:10.24432/C5TS3D
########## EXAMPLE ########## ### plot spatiotemporal component functions # data(eegcoord) # chnames <- rownames(eegcoord) # tseq <- seq(0,1,length.out=200) # quartz(width=18,height=6) # layout(matrix(c(1,2,3,4,5,6,7,8,9,10,11,11), 2, 6, byrow = TRUE)) # eegspace(eegcoord[,4:5],p1s(chnames),cex.point=1,main=expression(psi[p1]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p1t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p1]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],p2s(chnames),cex.point=1,main=expression(psi[p2]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p2t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p2]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],p3s(chnames),cex.point=1,main=expression(psi[p3]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p3t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p3]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],n1s(chnames),cex.point=1,main=expression(psi[n1]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,n1t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[n1]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],n2s(chnames),cex.point=1,main=expression(psi[n2]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,n2t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[n2]),cex.main=2, # xlab="Time After Stimulus (sec)") # plot(seq(-10,10),seq(-10,10),type="n",axes=FALSE,xlab="",ylab="") # text(0,8,labels=expression(omega[p1]*" = "*psi[p1]*tau[p1]),cex=2) # text(0,4,labels=expression(omega[n1]*" = "*psi[n1]*tau[n1]),cex=2) # text(0,0,labels=expression(omega[p2]*" = "*psi[p2]*tau[p2]),cex=2) # text(0,-4,labels=expression(omega[n2]*" = "*psi[n2]*tau[n2]),cex=2) # text(0,-8,labels=expression(omega[p3]*" = "*psi[p3]*tau[p3]),cex=2) ### plot simulated data at various time points # quartz(width=15,height=3) # tseq <- c(50,150,250,350,450)/1000 # par(mfrow=c(1,5)) # for(j in 1:5){ # eegspace(eegcoord[,4:5],eegsim(chnames,rep(tseq[j],87)),vlim=c(-6.8,5.5), # main=paste(tseq[j]*1000," ms"),cex.main=2) # }########## EXAMPLE ########## ### plot spatiotemporal component functions # data(eegcoord) # chnames <- rownames(eegcoord) # tseq <- seq(0,1,length.out=200) # quartz(width=18,height=6) # layout(matrix(c(1,2,3,4,5,6,7,8,9,10,11,11), 2, 6, byrow = TRUE)) # eegspace(eegcoord[,4:5],p1s(chnames),cex.point=1,main=expression(psi[p1]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p1t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p1]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],p2s(chnames),cex.point=1,main=expression(psi[p2]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p2t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p2]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],p3s(chnames),cex.point=1,main=expression(psi[p3]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,p3t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[p3]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],n1s(chnames),cex.point=1,main=expression(psi[n1]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,n1t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[n1]),cex.main=2, # xlab="Time After Stimulus (sec)") # eegspace(eegcoord[,4:5],n2s(chnames),cex.point=1,main=expression(psi[n2]),cex.main=2,vlim=c(-3,9)) # eegtime(tseq,n2t(tseq),ylim=c(-1,1),asp=1/2,main=expression(tau[n2]),cex.main=2, # xlab="Time After Stimulus (sec)") # plot(seq(-10,10),seq(-10,10),type="n",axes=FALSE,xlab="",ylab="") # text(0,8,labels=expression(omega[p1]*" = "*psi[p1]*tau[p1]),cex=2) # text(0,4,labels=expression(omega[n1]*" = "*psi[n1]*tau[n1]),cex=2) # text(0,0,labels=expression(omega[p2]*" = "*psi[p2]*tau[p2]),cex=2) # text(0,-4,labels=expression(omega[n2]*" = "*psi[n2]*tau[n2]),cex=2) # text(0,-8,labels=expression(omega[p3]*" = "*psi[p3]*tau[p3]),cex=2) ### plot simulated data at various time points # quartz(width=15,height=3) # tseq <- c(50,150,250,350,450)/1000 # par(mfrow=c(1,5)) # for(j in 1:5){ # eegspace(eegcoord[,4:5],eegsim(chnames,rep(tseq[j],87)),vlim=c(-6.8,5.5), # main=paste(tseq[j]*1000," ms"),cex.main=2) # }
Smooths single- or multi-channel electroencephalography (EEG) with respect to space and/or time. Uses the bigspline, bigtps, and bigssa functions (from bigsplines package) for smoothing.
eegsmooth(voltage, space = NULL, time = NULL, nknots = NULL, rparm = NULL, lambdas = NULL, skip.iter = TRUE, se.fit = FALSE, rseed = 1234)eegsmooth(voltage, space = NULL, time = NULL, nknots = NULL, rparm = NULL, lambdas = NULL, skip.iter = TRUE, se.fit = FALSE, rseed = 1234)
voltage |
Vector of recorded EEG voltage at each row in |
space |
Matrix of electrode coordinates (in three-dimensions) at which EEG was recorded. If |
time |
Vector of time points at which EEG was recorded. If |
nknots |
Number of knots to sample for smoothing. Positive integer. |
rparm |
Rounding parameter(s) to use for smoothing. See Notes and Examples. |
lambdas |
Smoothing parameter(s) to use for smoothing. |
skip.iter |
If |
se.fit |
If |
rseed |
Random seed to use for knot selection. Set |
For temporal smoothing only: an object of class "bigspline" (see bigspline).
For spatial smoothing only: an object of class "bigtps" (see bigtps).
For spatial-temporal smoothing: an object of class "bigssa" (see bigssa).
For temporal smoothing only (i.e., space=NULL), the input rparm should be a positive scalar less than 1. Larger values produce faster (but less accurate) approximations. Default is 0.01, which I recommend for temporal smoothing; rparm=0.005 may be needed for particuarly rough signals, and rparm=0.02 could work for smoother signals.
For spatial smoothing only (i.e., time=NULL), the input rparm should be a positive scalar giving the rounding unit for the spatial coordinates. For example, rparm=0.1 rounds each coordinate to the nearest 0.1 (same as round(space,1)).
For spatial-temporal smoothing (i.e., both space and time are non-null), the input rparm should be a list of the form rparm=list(space=0.1,time=0.01), where the 0.1 and 0.01 can be replaced by your desired rounding parameters.
Setting rparm=NA will use the full data solution; this is more computationally expensive, and typically produces a solution very similar to using rparm=0.01 (see references).
Nathaniel E. Helwig <[email protected]>
Helwig, N. E. (2013). Fast and stable smoothing spline analysis of variance models for large samples with applications to electroencephalography data analysis. Unpublished doctoral dissertation. University of Illinois at Urbana-Champaign. https://www.ideals.illinois.edu/items/44427
Helwig, N.E. (2015). bigsplines: Smoothing Splines for Large Samples. doi:10.32614/CRAN.package.bigsplines, R package version 1.1-1, https://CRAN.R-project.org/package=bigsplines
Helwig, N. E. & Ma, P. (2015). Fast and stable multiple smoothing parameter selection in smoothing spline analysis of variance models with large samples. Journal of Computational and Graphical Statistics, 24(3), 715-732. doi:10.1080/10618600.2014.926819
Helwig, N. E. & Ma, P. (2016). Smoothing spline ANOVA for super large samples: Scalable computation via rounding parameters. Statistics and Its Interface, 9(4), 433-444. doi:10.4310/SII.2016.v9.n4.a3
########## EXAMPLE 1: Temporal ########## # get "PZ" electrode of "c" subjects in "eegdata" data data(eegdata) idx <- which(eegdata$channel=="PZ" & eegdata$group=="c") eegdata <- eegdata[idx,] # temporal smoothing eegmod <- eegsmooth(eegdata$voltage,time=eegdata$time) # define data for prediction time <- seq(min(eegdata$time),max(eegdata$time),length.out=100) yhat <- predict(eegmod,newdata=time,se.fit=TRUE) # plot results using eegtime eegtime(time*1000/255,yhat$fit,voltageSE=yhat$se.fit,ylim=c(-4,4),main="Pz") ########## EXAMPLE 2: Spatial ########## # get time point 65 (approx 250 ms) of "c" subjects in "eegdata" data data(eegdata) idx <- which(eegdata$time==65L & eegdata$group=="c") eegdata <- eegdata[idx,] # remove ears, nose, and reference (Cz) idx <- c(which(eegdata$channel=="X"),which(eegdata$channel=="Y"), which(eegdata$channel=="nd"),which(eegdata$channel=="Cz")) eegdata <- eegdata[-idx,] # match to eeg coordinates data(eegcoord) cidx <- match(eegdata$channel,rownames(eegcoord)) # spatial smoothing eegmod <- eegsmooth(eegdata$voltage,space=eegcoord[cidx,1:3]) # use dense cap for prediction mycap <- levels(factor(eegdata$channel)) ix <- eegcapdense(mycap,type="2d",index=TRUE) data(eegdense) space <- eegdense[ix,1:3] yhat <- predict(eegmod,newdata=space) # plot results using eegspace #eegspace(space,yhat) eegspace(eegdense[ix,4:5],yhat) ########## EXAMPLE 3: Spatial-Temporal (not run) ########## # # get "c" subjects of "eegdata" data # data(eegdata) # idx <- which(eegdata$group=="c") # eegdata <- eegdata[idx,] # # remove ears, nose, and reference (Cz) # idx <- c(which(eegdata$channel=="X"),which(eegdata$channel=="Y"), # which(eegdata$channel=="nd"),which(eegdata$channel=="Cz")) # eegdata <- eegdata[-idx,] # # match to eeg coordinates # data(eegcoord) # cidx <- match(eegdata$channel,rownames(eegcoord)) # # spatial-temporal smoothing # eegmod <- eegsmooth(eegdata$voltage,space=eegcoord[cidx,1:3],time=eegdata$time) # # time main effect # newdata <- list(time=seq(min(eegdata$time),max(eegdata$time),length.out=100)) # yhat <- predict(eegmod,newdata=newdata,se.fit=TRUE,include="time") # eegtime(newdata$time,yhat$fit,voltageSE=yhat$se.fit,ylim=c(-2,4),main="Time Main Effect") # # space main effect # mycap <- levels(factor(eegdata$channel)) # ix <- eegcapdense(mycap,type="2d",index=TRUE) # data(eegdense) # newdata <- list(space=eegdense[ix,1:3]) # yhat <- predict(eegmod,newdata=newdata,include="space") # eegspace(newdata$space,yhat) # # interaction effect (spatial map at time point 65) # newdata <- list(space=eegdense[ix,1:3],time=rep(65,nrow(eegdense[ix,]))) # yhat <- predict(eegmod,newdata=newdata,include="space:time") # eegspace(newdata$space,yhat) # # full prediction (spatial map at time point 65) # newdata <- list(space=eegdense[ix,1:3],time=rep(65,nrow(eegdense[ix,]))) # yhat <- predict(eegmod,newdata=newdata) # eegspace(newdata$space,yhat)########## EXAMPLE 1: Temporal ########## # get "PZ" electrode of "c" subjects in "eegdata" data data(eegdata) idx <- which(eegdata$channel=="PZ" & eegdata$group=="c") eegdata <- eegdata[idx,] # temporal smoothing eegmod <- eegsmooth(eegdata$voltage,time=eegdata$time) # define data for prediction time <- seq(min(eegdata$time),max(eegdata$time),length.out=100) yhat <- predict(eegmod,newdata=time,se.fit=TRUE) # plot results using eegtime eegtime(time*1000/255,yhat$fit,voltageSE=yhat$se.fit,ylim=c(-4,4),main="Pz") ########## EXAMPLE 2: Spatial ########## # get time point 65 (approx 250 ms) of "c" subjects in "eegdata" data data(eegdata) idx <- which(eegdata$time==65L & eegdata$group=="c") eegdata <- eegdata[idx,] # remove ears, nose, and reference (Cz) idx <- c(which(eegdata$channel=="X"),which(eegdata$channel=="Y"), which(eegdata$channel=="nd"),which(eegdata$channel=="Cz")) eegdata <- eegdata[-idx,] # match to eeg coordinates data(eegcoord) cidx <- match(eegdata$channel,rownames(eegcoord)) # spatial smoothing eegmod <- eegsmooth(eegdata$voltage,space=eegcoord[cidx,1:3]) # use dense cap for prediction mycap <- levels(factor(eegdata$channel)) ix <- eegcapdense(mycap,type="2d",index=TRUE) data(eegdense) space <- eegdense[ix,1:3] yhat <- predict(eegmod,newdata=space) # plot results using eegspace #eegspace(space,yhat) eegspace(eegdense[ix,4:5],yhat) ########## EXAMPLE 3: Spatial-Temporal (not run) ########## # # get "c" subjects of "eegdata" data # data(eegdata) # idx <- which(eegdata$group=="c") # eegdata <- eegdata[idx,] # # remove ears, nose, and reference (Cz) # idx <- c(which(eegdata$channel=="X"),which(eegdata$channel=="Y"), # which(eegdata$channel=="nd"),which(eegdata$channel=="Cz")) # eegdata <- eegdata[-idx,] # # match to eeg coordinates # data(eegcoord) # cidx <- match(eegdata$channel,rownames(eegcoord)) # # spatial-temporal smoothing # eegmod <- eegsmooth(eegdata$voltage,space=eegcoord[cidx,1:3],time=eegdata$time) # # time main effect # newdata <- list(time=seq(min(eegdata$time),max(eegdata$time),length.out=100)) # yhat <- predict(eegmod,newdata=newdata,se.fit=TRUE,include="time") # eegtime(newdata$time,yhat$fit,voltageSE=yhat$se.fit,ylim=c(-2,4),main="Time Main Effect") # # space main effect # mycap <- levels(factor(eegdata$channel)) # ix <- eegcapdense(mycap,type="2d",index=TRUE) # data(eegdense) # newdata <- list(space=eegdense[ix,1:3]) # yhat <- predict(eegmod,newdata=newdata,include="space") # eegspace(newdata$space,yhat) # # interaction effect (spatial map at time point 65) # newdata <- list(space=eegdense[ix,1:3],time=rep(65,nrow(eegdense[ix,]))) # yhat <- predict(eegmod,newdata=newdata,include="space:time") # eegspace(newdata$space,yhat) # # full prediction (spatial map at time point 65) # newdata <- list(space=eegdense[ix,1:3],time=rep(65,nrow(eegdense[ix,]))) # yhat <- predict(eegmod,newdata=newdata) # eegspace(newdata$space,yhat)
Creates plot of multi-channel electroencephalography (EEG) spatial map. User can control the plot type (2d or 3d), the colormap, color, etc.
eegspace(space, voltage, vlim = NULL, mycolors = NULL, ncolor = 25, colorbar = TRUE, nctick = 5, rtick = 1, cex.axis = 1, barloc = NULL, colorlab = NULL, colorlabline = 3, cex.lab = 1, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = 1, cex.main = 1, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", mar = NULL, ...)eegspace(space, voltage, vlim = NULL, mycolors = NULL, ncolor = 25, colorbar = TRUE, nctick = 5, rtick = 1, cex.axis = 1, barloc = NULL, colorlab = NULL, colorlabline = 3, cex.lab = 1, plotaxes = FALSE, main = "", xyzlab = NULL, cex.point = 1, cex.main = 1, nose = TRUE, ears = TRUE, head = TRUE, col.head = "AntiqueWhite", mar = NULL, ...)
space |
Matrix of input electrode coordinates (3d or 2d). |
voltage |
Vector of recorded EEG voltage at each row in |
vlim |
Two-element vector giving the limits to use when mapping |
mycolors |
Character vector of colors to use for color mapping (such that |
ncolor |
Number of colors to use in mapping (positive integer). |
colorbar |
If |
nctick |
Approximate number of ticks for colorbar. Ignored if |
rtick |
Round tick labels to given decimal. Ignored if |
cex.axis |
Cex of axis ticks for colorbar. Ignored if |
barloc |
Character vector giving location of color bar. See Notes. |
colorlab |
Character vector giving label for color bar. Ignored if |
colorlabline |
Line number for color bar label (for input to |
cex.lab |
Cex of axis labels for colorbar. Ignored if |
plotaxes |
If |
main |
Plot title. Default is no title. |
xyzlab |
Axis labels to use for plot. If |
cex.point |
Cex for plotted electrodes. |
cex.main |
Cex for plot title. Ignored if |
nose |
If |
ears |
If |
head |
If |
col.head |
Color for dummy head in 3d plot. Ignored if |
mar |
Margins to use for plot (see |
... |
Optional inputs for |
Produces plot of EEG spatial map with NULL return value.
For 3d plots, barloc can be one of four options: "backright", "backleft", "frontright", or "frontleft". For 2d plots, barloc can be either "right" or "left".
Currently supports spatial maps registered to the 84-channel cap produced by eegcap and eegcoord.
Nathaniel E. Helwig <[email protected]>
Begleiter, H. (1995). EEG Database [Dataset]. UCI Machine Learning Repository. doi:10.24432/C5TS3D
########## EXAMPLE ########## # get time point 65 (approx 250 ms) from "eegdata" data data(eegdata) idx <- which(eegdata$time==65L) eegdata <- eegdata[idx,] # get average spatial map eegmean <- tapply(eegdata$voltage,list(eegdata$channel,eegdata$group),mean) # remove ears and nose acnames <- rownames(eegmean) idx <- c(which(acnames=="X"),which(acnames=="Y"),which(acnames=="nd"),which(acnames=="Cz")) eegmean <- eegmean[-idx,] # match to eeg coordinates data(eegcoord) cidx <- match(rownames(eegmean),rownames(eegcoord)) # # plot average control voltage in 3d # open3d() # eegspace(eegcoord[cidx,1:3],eegmean[,2]) # plot average control voltage in 2d eegspace(eegcoord[cidx,4:5],eegmean[,2]) # # change 3d bar location and use play3d to rotate (not run) # open3d() # par3d(windowRect=c(0,0,600,600)) # eegspace(eegcoord[cidx,1:3],eegmean[,2],barloc="frontleft") # play3d(spin3d(axis=c(0,0,1),rpm=5),duration=20) # change 2d bar location eegspace(eegcoord[cidx,4:5],eegmean[,2],barloc="left")########## EXAMPLE ########## # get time point 65 (approx 250 ms) from "eegdata" data data(eegdata) idx <- which(eegdata$time==65L) eegdata <- eegdata[idx,] # get average spatial map eegmean <- tapply(eegdata$voltage,list(eegdata$channel,eegdata$group),mean) # remove ears and nose acnames <- rownames(eegmean) idx <- c(which(acnames=="X"),which(acnames=="Y"),which(acnames=="nd"),which(acnames=="Cz")) eegmean <- eegmean[-idx,] # match to eeg coordinates data(eegcoord) cidx <- match(rownames(eegmean),rownames(eegcoord)) # # plot average control voltage in 3d # open3d() # eegspace(eegcoord[cidx,1:3],eegmean[,2]) # plot average control voltage in 2d eegspace(eegcoord[cidx,4:5],eegmean[,2]) # # change 3d bar location and use play3d to rotate (not run) # open3d() # par3d(windowRect=c(0,0,600,600)) # eegspace(eegcoord[cidx,1:3],eegmean[,2],barloc="frontleft") # play3d(spin3d(axis=c(0,0,1),rpm=5),duration=20) # change 2d bar location eegspace(eegcoord[cidx,4:5],eegmean[,2],barloc="left")
Creates plot of single-channel electroencephalography (EEG) time course with optional confidence interval. User can control the plot orientation, line types, line colors, etc.
eegtime(time, voltage, flipvoltage = TRUE, vlty = 1, vlwd = 2, vcol = "blue", voltageSE = NULL, slty = NA, slwd = 1, scol = "cyan", salpha = 0.65, conflevel = 0.95, plotzero = TRUE, zlty = 1, zlwd = 0.5, zcol = "black", xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL, nxtick = 6, nytick = 6, xticks = NULL, yticks = NULL, add = FALSE, ...)eegtime(time, voltage, flipvoltage = TRUE, vlty = 1, vlwd = 2, vcol = "blue", voltageSE = NULL, slty = NA, slwd = 1, scol = "cyan", salpha = 0.65, conflevel = 0.95, plotzero = TRUE, zlty = 1, zlwd = 0.5, zcol = "black", xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL, nxtick = 6, nytick = 6, xticks = NULL, yticks = NULL, add = FALSE, ...)
time |
Vector of time points at which EEG was recorded. |
voltage |
Vector of recorded EEG voltage at each point in |
flipvoltage |
If |
vlty |
Line type for |
vlwd |
Line width for |
vcol |
Line color for |
voltageSE |
Vector of standard errors of EEG voltage at each point in |
slty |
Line type for |
slwd |
Line width for |
scol |
Polygon or line color for |
salpha |
Transparency value for |
conflevel |
Confidence level to use for confidence intervals. Default forms 95% CI. |
plotzero |
If |
zlty |
Line type for reference line. Ignored if |
zlwd |
Line width for reference line. Ignored if |
zcol |
Line color for reference line. Ignored if |
xlim |
Plot limits for |
ylim |
Plot limits for |
xlab |
Plot label for |
ylab |
Plot label for |
nxtick |
Approximate number of axis ticks for |
nytick |
Approximate number of axis ticks |
xticks |
x-axis ticks for |
yticks |
y-axis ticks |
add |
If |
... |
Optional inputs for |
Produces plot of EEG time course with NULL return value.
Confidence intervals are formed using the normal (Gaussian) distribution.
Nathaniel E. Helwig <[email protected]>
Begleiter, H. (1995). EEG Database [Dataset]. UCI Machine Learning Repository. doi:10.24432/C5TS3D
########## EXAMPLE ########## # get "PZ" electrode from "eegdata" data data(eegdata) idx <- which(eegdata$channel=="PZ") eegdata <- eegdata[idx,] # get average and standard error (note se=sd/sqrt(n)) eegmean <- tapply(eegdata$voltage,list(eegdata$time,eegdata$group),mean) eegse <- tapply(eegdata$voltage,list(eegdata$time,eegdata$group),sd)/sqrt(50) # plot results with legend tseq <- seq(0,1000,length.out=256) eegtime(tseq,eegmean[,2],voltageSE=eegse[,2],ylim=c(-10,6),main="Pz") eegtime(tseq,eegmean[,1],vlty=2,vcol="red",voltageSE=eegse[,1],scol="pink",add=TRUE) legend("bottomright",c("controls","alcoholics"),lty=c(1,2), lwd=c(2,2),col=c("blue","red"),bty="n")########## EXAMPLE ########## # get "PZ" electrode from "eegdata" data data(eegdata) idx <- which(eegdata$channel=="PZ") eegdata <- eegdata[idx,] # get average and standard error (note se=sd/sqrt(n)) eegmean <- tapply(eegdata$voltage,list(eegdata$time,eegdata$group),mean) eegse <- tapply(eegdata$voltage,list(eegdata$time,eegdata$group),sd)/sqrt(50) # plot results with legend tseq <- seq(0,1000,length.out=256) eegtime(tseq,eegmean[,2],voltageSE=eegse[,2],ylim=c(-10,6),main="Pz") eegtime(tseq,eegmean[,1],vlty=2,vcol="red",voltageSE=eegse[,1],scol="pink",add=TRUE) legend("bottomright",c("controls","alcoholics"),lty=c(1,2), lwd=c(2,2),col=c("blue","red"),bty="n")
Creates plot of multi-channel electroencephalography (EEG) time courses with subplots positioned according to electrode locations. User can control the plot orientation, line types, line colors, etc.
eegtimemc(time, voltmat, channel, size = c(0.75,0.75), vadj = 0.5, hadj = 0.5, xlab = "", ylab = "", voltSE = NULL, vlty = 1, slty = NA, vlwd = 1, slwd = 1, vcol = "blue", scol = "cyan", ...)eegtimemc(time, voltmat, channel, size = c(0.75,0.75), vadj = 0.5, hadj = 0.5, xlab = "", ylab = "", voltSE = NULL, vlty = 1, slty = NA, vlwd = 1, slwd = 1, vcol = "blue", scol = "cyan", ...)
time |
Vector of time points at which EEG was recorded. |
voltmat |
Matrix of multi-channel EEG voltages (time by channel). |
channel |
Character vector giving name of channel for each column of |
size |
Relative size of each subplot. |
vadj |
Vertical adjustment for each subplot. |
hadj |
Horizontal adjustment for each subplot. |
xlab |
X-axis label for each subplot. |
ylab |
Y-axis label for each subplot. |
voltSE |
Matrix of voltage standard errors (same size as |
vlty |
Line type for |
slty |
Line type for |
vlwd |
Line width for |
slwd |
Line width for |
vcol |
Line color for |
scol |
Polygon or line color for |
... |
Optional inputs for |
Produces plot of EEG time course with NULL return value.
Currently supports 84 scalp electrodes (plus ears and nose): A1 A2 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AFZ C1 C2 C3 C4 C5 C6 CP1 CP2 CP3 CP4 CP5 CP6 CPZ CZ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 FC1 FC2 FC3 FC4 FC5 FC6 FCZ FP1 FP2 FPZ FT7 FT8 FT9 FT10 FZ I1 I2 IZ NZ O1 O2 OZ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 POZ PZ T7 T8 T9 T10 TP7 TP8 TP9 TP10
Subplots are created using eegtime, so input ... can be any optional input for eegtime.
Inspired by Frank Harrell's subplot function (in Hmisc package).
Nathaniel E. Helwig <[email protected]>
Begleiter, H. (1995). EEG Database [Dataset]. UCI Machine Learning Repository. doi:10.24432/C5TS3D
Harrell Jr F (2025). Hmisc: Harrell Miscellaneous. doi:10.32614/CRAN.package.Hmisc, R package version 5.2-3, https://CRAN.R-project.org/package=Hmisc
########## EXAMPLE ########## # # get control ("c") data from "eegdata" data # data(eegdata) # idx <- which(eegdata$group=="c") # eegdata <- eegdata[idx,] # # get average # eegmean <- tapply(eegdata$voltage,list(eegdata$time,eegdata$channel),mean) # eegse <- tapply(eegdata$voltage,list(eegdata$time,eegdata$channel),sd)/sqrt(50) # # plot time course for all electrodes # dev.new(height=15,width=15, noRStudioGD = TRUE) # tseq <- seq(0,1000,length.out=256) # eegtimemc(tseq,eegmean,colnames(eegmean),ylim=c(-11,14),voltSE=eegse)########## EXAMPLE ########## # # get control ("c") data from "eegdata" data # data(eegdata) # idx <- which(eegdata$group=="c") # eegdata <- eegdata[idx,] # # get average # eegmean <- tapply(eegdata$voltage,list(eegdata$time,eegdata$channel),mean) # eegse <- tapply(eegdata$voltage,list(eegdata$time,eegdata$channel),sd)/sqrt(50) # # plot time course for all electrodes # dev.new(height=15,width=15, noRStudioGD = TRUE) # tseq <- seq(0,1000,length.out=256) # eegtimemc(tseq,eegmean,colnames(eegmean),ylim=c(-11,14),voltSE=eegse)