I am working with a dataset of exposure over time and I would like to get all peaks over 1. I am doing it with the function pracma::findpeaks(), but the output I get it's not what I really want and I don't find how to fix it.
Here is an example with the code I am using:
#### Exemple ####
## Create dataset
time_initial <- seq(from = as.POSIXct("08:19:00", "%H:%M:%S", tz="UTC"), to = as.POSIXct("08:19:19", "%H:%M:%S", tz="UTC"), by = "1 sec")
time_min <- format(as.POSIXct(time_initial), format = '%H:%M:%S')
exposure <- c(0,0,2,3,5,0,0,4,5,6,0.5,0.25,0,0,0,0,4,5,0,0)
data <- as.data.frame(cbind(time_min, exposure))
## call peaks
data$exposure <- as.numeric(data$exposure)
peak <- findpeaks(data$exposure, nups = 1, ndowns = 1, sortstr = FALSE, threshold = 1)
## return times and not positions
peak_info <- data.frame(
peak_number = 1:nrow(peak),
time_peak_max = data[peak[,2],"time_min"],
peak_heigth = data[peak[,2],"exposure"],
peak_start = data[peak[,3],"time_min"],
peak_end = data[peak[,4],"time_min"])
The ouput I get returns all the peak, from 0 to 0, but I would like to get it from the first exposure over 1 to the last exposure over 1. With my example, the ideal code would return me the same 3 peaks, but for the intervals (08:19:02 - 08:19:04) ; (08:19:07 - 08:19:09) ; (08:19:16 - 08:19:17).
Maybe I'm not doing it with the correct function, but it is my first time working with peaks and I thought this would work.
Many thanks,
Miquel
CodePudding user response:
Like my colleague @Wimpel, I tried to approach this without using the pracma::findpeaks()
function.. Here is a dplyr
approach, that also borrows data.table::rleid()
library(dplyr)
data %>%
mutate(peak=data.table::rleid(exposure>1)) %>%
filter(exposure>1) %>%
group_by(peak) %>%
summarize(lb = min(time_min), ub=max(time_min), peak_value = max(exposure), peak_time=time_min[which.max(exposure)[1]]) %>%
mutate(peak = row_number())
Output:
peak lb ub peak_value peak_time
<int> <chr> <chr> <dbl> <chr>
1 1 08:19:02 08:19:04 5 08:19:04
2 2 08:19:07 08:19:09 6 08:19:09
3 3 08:19:16 08:19:17 5 08:19:17
CodePudding user response:
data.table
approach
library(data.table)
# convert to data.table
setDT(data)
# identify groups
data[, group := rleid(exposure >= 1)]
# get min/max of non-zero-exposure groups
data[exposure >= 1, .(from = min(time_min), to = max(time_min)), by = group]
# group from to
# 1: 2 08:19:02 08:19:04
# 2: 4 08:19:07 08:19:09
# 3: 6 08:19:16 08:19:17