Introduction
Event-related skin conductance response (ER-SCR) analysis examines phasic EDA changes that are time-locked to experimental events (e.g., stimulus presentations, decisions, or feedback). This is the most common paradigm in psychophysiology research using EDA.
This vignette demonstrates how to use PhysioEDA to perform event-related SCR analysis, from data preparation through statistical summary of event-locked responses.
Overview of the ER-SCR Workflow
The typical event-related SCR analysis pipeline consists of:
- Load or simulate EDA data with event markers
- Preprocess the signal (filter, artifact correction)
- Decompose into tonic and phasic components
- Extract event-related SCR features
- Summarize and analyze results
Preparing Data with Events
For event-related analysis, the PhysioExperiment object must contain event markers. These can be imported from experimental software or added manually.
library(PhysioEDA)
# Generate simulated EDA with 4 stimulus events
x <- make_eda_with_scr(n_time = 6000, sr = 10, n_events = 4)
# Inspect the events
events <- getEvents(x)
eventsAdding Events Manually
If your data does not already contain events, you can add them using
setEvents():
library(PhysioCore)
x_plain <- make_eda(n_time = 6000, sr = 10)
# Define stimulus events
x_plain <- setEvents(x_plain, PhysioEvents(
onset = c(60, 120, 240, 360),
duration = c(0.5, 0.5, 0.5, 0.5),
type = c("stimulus", "stimulus", "stimulus", "stimulus"),
value = c("CS+", "CS-", "CS+", "CS-")
))Preprocessing for ER-SCR
The preprocessing steps are the same as for general EDA analysis: filtering and artifact correction. It is important to complete preprocessing before decomposition.
# Lowpass filter to remove noise
x <- edaFilter(x, type = "lowpass", cutoff = 1.0)
# Detect and correct artifacts
x <- edaArtifact(x, correct = "interpolate")Decomposition
For event-related analysis, the Continuous Decomposition Analysis (CDA) method is recommended as it provides a physiologically meaningful driver signal.
x <- edaDecompose(x, method = "cda", tau1 = 0.75, tau2 = 2.0)
# Verify that tonic and phasic assays exist
SummarizedExperiment::assayNames(x)Event-Related SCR Extraction
The edaErscr() function is the core of event-related
analysis. For each event, it searches for an SCR onset within a
specified latency window and extracts amplitude, latency, rise time, and
50% recovery time.
Understanding the Parameters
-
onset_window: The valid latency range (in seconds)
after event onset in which an SCR onset must occur to be considered
event-related. The default
c(1, 4)reflects the typical 1-4 second latency of sympathetic responses. -
peak_window: The minimum and maximum time from SCR
onset to its peak (default:
c(0.5, 5)). - amplitude_min: The minimum amplitude threshold for a valid SCR (default: 0.01 microsiemens).
Interpreting the Results
The returned data.frame contains one row per event per channel with the following columns:
| Column | Description |
|---|---|
event_index |
Sequential index of the event |
event_onset |
Event onset time in seconds |
channel |
Channel label |
scr_present |
Whether a valid SCR was detected |
scr_amplitude |
SCR amplitude (peak minus onset value) |
scr_latency |
Latency from event to SCR onset |
scr_rise_time |
Time from SCR onset to peak |
scr_recovery_time |
Time for 50% recovery from peak |
Working with ER-SCR Results
Response Rate
The SCR response rate is an important measure that indicates the proportion of trials that elicited a detectable SCR.
Mean Amplitude
When computing mean amplitudes, a common approach is to include only trials with a valid SCR (responders-only) or to set non-responder amplitudes to zero.
# Responders-only mean amplitude
responders <- er_results[er_results$scr_present, ]
if (nrow(responders) > 0) {
mean_amp <- mean(responders$scr_amplitude, na.rm = TRUE)
cat("Mean SCR amplitude (responders):", round(mean_amp, 3), "uS\n")
}
# All-trials mean (non-responders = 0)
er_results$amplitude_zero <- ifelse(er_results$scr_present,
er_results$scr_amplitude, 0)
mean_amp_all <- mean(er_results$amplitude_zero)
cat("Mean SCR amplitude (all trials):", round(mean_amp_all, 3), "uS\n")Comparing Conditions
When events have different types or values, you can compare SCR features across conditions.
# If events have different types, filter by event type
# Example: comparing CS+ vs CS- in a conditioning paradigm
# Get event metadata
events <- getEvents(x)
event_df <- events@events
# Merge event metadata with ER-SCR results
er_results$event_value <- event_df$value[er_results$event_index]
# Compare conditions (using base R)
by_condition <- split(er_results, er_results$event_value)
condition_summary <- do.call(rbind, lapply(names(by_condition), function(cond) {
d <- by_condition[[cond]]
data.frame(
condition = cond,
n_trials = nrow(d),
response_rate = mean(d$scr_present),
mean_amplitude = mean(d$scr_amplitude, na.rm = TRUE),
mean_latency = mean(d$scr_latency, na.rm = TRUE),
stringsAsFactors = FALSE
)
}))
condition_summaryData Transformation for Statistics
SCR amplitudes are typically right-skewed. Before parametric statistical tests, consider applying a log or square root transformation.
# Log transform the amplitudes
if (any(er_results$scr_present)) {
er_results$log_amplitude <- log1p(er_results$scr_amplitude)
# Or use the full-signal transform
x_log <- edaTransform(x, method = "log")
}Complete Event-Related Analysis Example
library(PhysioEDA)
# Step 1: Create data with events
x <- make_eda_with_scr(n_time = 6000, sr = 10, n_events = 4)
# Step 2: Preprocess
x <- edaFilter(x, type = "lowpass", cutoff = 1.0)
x <- edaArtifact(x, correct = "interpolate")
# Step 3: Decompose
x <- edaDecompose(x, method = "cda")
# Step 4: Extract event-related SCRs
er_results <- edaErscr(x, onset_window = c(1, 4), amplitude_min = 0.01)
# Step 5: Summarize
cat("Event-Related SCR Summary\n")
cat("=========================\n")
cat("Total events:", nrow(er_results), "\n")
cat("Response rate:", round(mean(er_results$scr_present) * 100, 1), "%\n")
if (any(er_results$scr_present)) {
resp <- er_results[er_results$scr_present, ]
cat("Mean amplitude:", round(mean(resp$scr_amplitude), 3), "uS\n")
cat("Mean latency:", round(mean(resp$scr_latency), 2), "s\n")
cat("Mean rise time:", round(mean(resp$scr_rise_time), 2), "s\n")
}
# Step 6: Visualize
plotDecompose(x, channel = 1)
plotEda(x, show_events = TRUE)Best Practices
Onset window: Use 1-4 seconds for typical sympathetic response latencies. Adjust for your paradigm if needed (e.g., shorter for startle responses).
Amplitude threshold: The conventional minimum is 0.01-0.05 microsiemens. Use a consistent threshold across all participants and conditions.
Decomposition method: CDA is recommended for event-related analyses as it provides better temporal resolution of overlapping SCRs than simple highpass filtering.
Non-responders: Decide a priori whether to analyze responders only or to score non-responders as zero amplitude. Report which approach was used.
Multiple channels: If recording from multiple sites, analyze each channel separately. The results data.frame includes a channel column for this purpose.
References
- Bach, D.R., et al. (2010). Modelling event-related skin conductance responses. International Journal of Psychophysiology, 75(3), 349-356.
- Benedek, M., & Kaernbach, C. (2010). A continuous measure of phasic electrodermal activity. Journal of Neuroscience Methods, 190(1), 80-91.
- Boucsein, W. (2012). Electrodermal Activity. 2nd ed. Springer.