Nothing
## ---- include = FALSE---------------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
## ----setup--------------------------------------------------------------------
library(musclesyneRgies)
## ---- eval = FALSE------------------------------------------------------------
# # Load package
# library(musclesyneRgies)
#
# # The simplest formulation, using the native (R >= `4.1.0`) pipe operator
# # Here, the raw data set is already in the correct format and named `RAW_DATA`
# SYNS_classified <- lapply(RAW_DATA, function(x) subsetEMG(x, cy_max = 32)) |>
# lapply(filtEMG) |>
# lapply(function(x) normEMG(x, cy_max = 30, cycle_div = c(100, 100))) |>
# lapply(synsNMF) |>
# classify_kmeans()
#
# # Alternatively, one can save every step for subsequent inspection/analysis as follows
# # Read raw data from ASCII files
# RAW_DATA <- rawdata(header_cycles = FALSE)
# # Subset EMG to reduce the amount of data to the first 32 available cycles
# RAW_DATA <- lapply(RAW_DATA, function(x) subsetEMG(x, cy_max = 32))
# # Filter EMG
# FILT_DATA <- lapply(RAW_DATA, filtEMG)
# # Normalise filtered EMG, trim first and last cycle (32 were available, 30 will be left)
# # and divide cycle into two phases of 100 data points each
# NORM_EMG <- lapply(FILT_DATA, function(x) normEMG(x, cy_max = 30, cycle_div = c(100, 100)))
# # Extract synergies
# SYNS <- lapply(NORM_EMG, synsNMF)
# # Classify synergies with k-means
# # (the result is equivalent to the previous obtained with piping)
# SYNS_classified <- classify_kmeans(SYNS)
## -----------------------------------------------------------------------------
data("RAW_DATA")
head(RAW_DATA[[1]]$cycles)
head(RAW_DATA[[1]]$emg)
## -----------------------------------------------------------------------------
# Load built-in data set
data("RAW_DATA")
# Get current working directory
data_path <- getwd()
data_path <- paste0(data_path, .Platform$file.sep)
# Create two conveniently-named subfolders if they don't already exist
# (if they exist, please make sure they're empty!)
dir.create("cycles", showWarnings = FALSE)
dir.create("emg", showWarnings = FALSE)
# Export ASCII data from built-in data set to the new subfolders
write.table(RAW_DATA[[1]]$cycles,
file = paste0(data_path, "cycles", .Platform$file.sep, names(RAW_DATA)[1], ".txt"),
sep = "\t", row.names = FALSE
)
write.table(RAW_DATA[[1]]$emg,
file = paste0(data_path, "emg", .Platform$file.sep, names(RAW_DATA)[1], ".txt"),
sep = "\t", row.names = FALSE
)
# Run the function to parse ASCII files into objects of class `EMG`
raw_data_from_files <- rawdata(
path_cycles = paste0(data_path, "/cycles/"),
path_emg = paste0(data_path, "/emg/"),
header_cycles = FALSE
)
# Check data in the new folders if needed before running the following (will delete!)
# Delete folders
unlink("cycles", recursive = TRUE)
unlink("emg", recursive = TRUE)
## ---- message = FALSE, results = "hide"---------------------------------------
# Load the built-in example data set
data("RAW_DATA")
# Say you recorded more cycles than those you want to consider for the analysis
# You can subset the raw data (here we keep only 3 cycles, starting from the first)
RAW_DATA_subset <- lapply(
RAW_DATA,
function(x) {
subsetEMG(x,
cy_max = 3,
cy_start = 1
)
}
)
# The raw EMG data set then needs to be filtered
# If you don't want to subset the data set, just filter it as it is
# Here we filter the whole data set with the default parameters for locomotion:
# - Demean EMG
# - High-pass IIR Butterworth 4th order filter (cut-off frequency 50 Hz)
# - Full-wave rectification (default)
# - Low-pass IIR Butterworth 4th order filter (cut-off frequency 20 Hz)
# - Minimum subtraction
# - Amplitude normalisation
filtered_EMG <- lapply(RAW_DATA, function(x) filtEMG(x))
# If you decide to change filtering parameters, just give them as arguments:
another_filtered_EMG <- lapply(
RAW_DATA,
function(x) {
filtEMG(x,
demean = FALSE,
rectif = "halfwave",
HPf = 30,
HPo = 2,
LPf = 10,
LPo = 2,
min_sub = FALSE,
ampl_norm = FALSE
)
}
)
# Now the filtered EMG needs some time normalisation so that cycles will be comparable
# Here we time-normalise the filtered EMG, including only three cycles and trimming first
# and last to remove unwanted filtering effects
# Each cycle is divided into two parts, each normalised to a length of 100 points
norm_EMG <- lapply(
filtered_EMG,
function(x) {
normEMG(x,
trim = TRUE,
cy_max = 3,
cycle_div = c(100, 100)
)
}
)
# If this cycle division does not work for you, it can be changed
# But please remember to have the same amount of columns in the cycle times as the number
# of phases you want your cycles to be divided into
# Here we divide each cycle with a ratio of 60%-40% and keep only two cycles (first and last
# are still trimmed, so to have two cycles you must start with at least four available)
another_norm_EMG <- lapply(
filtered_EMG,
function(x) {
normEMG(x,
trim = TRUE,
cy_max = 2,
cycle_div = c(120, 80)
)
}
)
# At this stage, synergies can be extracted
# This is the core function to extract synergies via NMF
SYNS <- lapply(norm_EMG, synsNMF)
# Now synergies don't have a functional order and need classification
# Let's load the built-in data set to have some more trial to classify
# (clustering cannot be done on only one trial and having just a few,
# say less than 10, won't help)
data("SYNS")
# Classify with k-means# and producing a plot that shows how the clustering went with:
# - Full width at half maximum on the x-axis
# - Centre of activity on the y-axis
# (both referred to the motor primitives of the classified muscle synergies)
SYNS_classified <- classify_kmeans(SYNS)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.