PhysioCore provides the PhysioExperiment class, a
Bioconductor-compatible data structure for multi-modal physiological
signal data. Built on top of SummarizedExperiment, it adds
a sampling rate slot and convenience functions for channel management,
event handling, and signal utilities.
This vignette covers the basics of creating
PhysioExperiment objects, accessing and modifying their
contents, and managing channel metadata.
The PhysioExperiment() constructor accepts assay data
(as a list of matrices or arrays), channel metadata via
colData, and a sampling rate in Hz.
library(PhysioCore)
# Simulate 4 seconds of 4-channel EEG data at 250 Hz
n_time <- 1000
n_channels <- 4
sr <- 250
eeg_data <- matrix(rnorm(n_time * n_channels), nrow = n_time, ncol = n_channels)
pe <- PhysioExperiment(
assays = list(raw = eeg_data),
colData = S4Vectors::DataFrame(
label = c("Fz", "Cz", "Pz", "Oz"),
type = rep("EEG", n_channels)
),
samplingRate = sr
)
peYou can store multiple processing stages as separate assays. For example, a raw signal and a filtered version:
PhysioCore provides a rich set of functions for managing channel metadata.
# Rename channels
channelNames(pe) <- c("F3", "C3", "P3", "O1")
channelNames(pe)
# Or rename specific channels
pe <- renameChannels(pe, old_names = "F3", new_names = "Fz")
# Set channel types
pe <- setChannelTypes(pe, c("EEG", "EEG", "EEG", "EEG"))
# Set channel types by name
pe <- setChannelTypes(pe, c(Fz = "EEG"))
# Set physical units
pe <- setChannelUnits(pe, "uV")# Pick channels by name
pe_frontal <- pickChannels(pe, c("Fz", "C3"))
nChannels(pe_frontal)
# Pick channels by index
pe_subset <- pickChannels(pe, c(1, 3))
# Drop channels
pe_dropped <- dropChannels(pe, "O1")
nChannels(pe_dropped)
# Get channel indices by type
eeg_idx <- getChannelsByType(pe, "EEG")# Apply a standard 10-20 montage
pe <- applyMontage(pe, "10-20")
# Read electrode positions
positions <- getElectrodePositions(pe)
head(positions)
# Set custom positions
custom_pos <- data.frame(
x = c(0, 0, 0, 0),
y = c(0.71, 0, -0.71, -1.0),
z = c(0.71, 1.0, 0.71, 0)
)
pe <- setElectrodePositions(pe, custom_pos)# Combine by channels (same time points required)
pe1 <- pickChannels(pe, c(1, 2))
pe2 <- pickChannels(pe, c(3, 4))
pe_combined <- cbindPhysio(pe1, pe2)
nChannels(pe_combined)
# Combine by time (same channels required)
pe_first <- pe[1:500, ]
pe_second <- pe[501:1000, ]
pe_concat <- rbindPhysio(pe_first, pe_second)
length(pe_concat)PhysioCore provides utilities for checking and handling missing values:
# Check for NA presence
hasNA(pe)
# Detailed NA check
checkNA(pe)
# NA summary across all assays
naSummary(pe)
# Replace NA values in an assay
pe_clean <- replaceNA(pe, method = "interpolate")
# Handle NA in a numeric vector
x <- c(1, NA, 3, NA, 5)
handleNA(x, method = "interpolate")
handleNA(x, method = "locf")
# Fill edge NA values
y <- c(NA, NA, 1, 2, 3, NA)
fillEdgeNA(y, method = "extend")vignette("event-handling", package = "PhysioCore")
for working with experimental events and triggers.