This is a followup question to my original "Count Peaks with R" question.
In this question I want to use standard deviations to derive thresholds per person in the dataset...
Here is fake data to make my everything reproducible:
set.seed(9494)
Happiness <- round(runif(100, -100, 100))
ID <- rep(c("ID1", "ID2", "ID3", "ID4", "ID5"), 20)
Stimuli <- rep(1:4, 1)
DF <- data.frame(ID, Stimuli, Happiness)
Explanation: Dataframe "DF" is a summary of 5 people that each looked at 3 different stimuli. Happiness is the emotion that they experienced while looking at the stimuli for a certain period of time (in the dataframe each row is a different portion of 1 second)
Thanks to dcarlson's input on my previous question, this question builds on counting peaks in R by taking the standard deviation of each ID's respective Happiness across all stimuli watched.
Step 1: calculate thresholds per person (DF$ID)
First, I want to split the dataframe DF by ID:
#split dataframe per ID AND stimuli
DF.id <- split(DF, DF$ID)
Next I created this function to calculate the thresholds per person (ID):
TR_SD <- function(Y){
SD1_thresh <- mean(Y) + (1*sd(Y))
SD2_thresh <- mean(Y) + (2*sd(Y))
SD3_thresh <- mean(Y) + (3*sd(Y))
SD1_neg_thresh <- mean(Y) - (1*sd(Y))
SD2_neg_thresh <- mean(Y) - (2*sd(Y))
SD3_neg_thresh <- mean(Y) - (3*sd(Y))
return(cbind(SD1_thresh, SD2_thresh, SD3_thresh, SD1_neg_thresh, SD2_neg_thresh, SD3_neg_thresh))
}
SD.Thresh <- lapply(DF.id, function(ID) TR_SD(ID$Happiness))
SD.Thresh
Step 2: Now the function that determines whether each Happiness value is above (TRUE = 1) or below (FALSE = 0) the above thresholds to count the peaks:
#function to create matrix that analyzes Happiness based on threshholds
Thresh <- function(X) {
H_peaks_1a <- ifelse(X >= SD1_thresh ,1,0)
H_peaks_2a <- ifelse(X >= SD2_thresh,1,0)
H_peaks_3a <- ifelse(X >= SD3_thresh,1,0)
H_neg_peaks_1a <- ifelse(X <= SD1_neg_thresh ,1,0)
H_neg_peaks_2a <- ifelse(X <= SD2_neg_thresh ,1,0)
H_neg_peaks_3a <- ifelse(X <= SD3_neg_thresh ,1,0)
return(cbind(H_peaks_1a, H_peaks_2a, H_peaks_3a, H_neg_peaks_1a, H_neg_peaks_2a, H_neg_peaks_3a))
}
#run function
H_peaks.ID <- lapply(DF.id, function(ID) Thresh(ID$Happiness))
Question: how can I use the threshold results out of SD.Thresh per person (ID) as individual thresholds to apply to each respective ID to then count the peaks?
Use the ID1 results here...
... as thresholds for ID1 when counting peaks
Thresh <- function(X) {
H_peaks_1a <- ifelse(X >= SD1_thresh ,1,0)
H_peaks_2a <- ifelse(X >= SD2_thresh,1,0)
H_peaks_3a <- ifelse(X >= SD3_thresh,1,0)
H_neg_peaks_1a <- ifelse(X <= SD1_neg_thresh ,1,0)
H_neg_peaks_2a <- ifelse(X <= SD2_neg_thresh ,1,0)
H_neg_peaks_3a <- ifelse(X <= SD3_neg_thresh ,1,0)
return(cbind(H_peaks_1a, H_peaks_2a, H_peaks_3a, H_neg_peaks_1a, H_neg_peaks_2a, H_neg_peaks_3a))
}
Step 3: count peaks above thresholds
#count peaks
peaks <- t(sapply(H_peaks.ID, function(x) apply(x, 2, function(y) sum(diff(c(y, 0)) < 0))))
peaks <- as.data.frame(peaks)
peaks
Step 4: count time above thresholds
#total time / frames above threshhold
time <- t(sapply(H_peaks.ID, function(x) apply(x, 2, sum)))
time <- as.data.frame(time)
time