Вопрос или проблема
Я работаю с двумя наборами данных. Первый набор данных содержит значения флуоресценции, измеренные каждую минуту. Второй набор данных содержит определенные события и их время. Мы знаем, что эти события вызывают пики значений флуоресценции незадолго до и почти сразу после времени события.
Упрощенный воспроизводимый пример на R:
Здесь я предоставляю упрощенную версию кода R, который я использую для связи значений флуоресценции с событиями. У меня есть серия значений флуоресценции, измеренных каждую минуту. Затем у меня есть второй набор данных с тремя событиями A, B и C, которые происходят в три разных времени. Кажется, что вокруг каждого события есть три больших пика в значении флуоресценции.
Цель состоит в том, чтобы классифицировать каждое значение как соответствующее событию, когда время этого значения попадает в пределах 15 минут от времени события. Значения флуоресценции, которые находятся вне любых событий, классифицируются как NA.
Установить сид
set.seed(10)
Сгенерировать набор данных значений флуоресценции и набор данных событий
values <- data.table(date.time.value=seq(ymd_hms("2018-01-01 00:00:00"), by= "min", length.out = 200),fluor=5*sin(seq(0,20,length.out = 200)))+(abs(rnorm(200,6,1))+2)
events <- data.table(event=c("A","B","C"),date.time.event=c(ymd_hms("2018-01-01 00:20:00"),ymd_hms("2018-01-01 01:20:00"),ymd_hms("2018-01-01 02:20:00")))
Используя пакет data.table: я добавляю переменную “событие” в набор данных значений. Эта переменная принимает название события (в данном случае A, B или C) всякий раз, когда date.time.value находится в пределах 15 минут от date.time.event.
values[, event:=events[.SD[, .(d_dn=date.time.value-15*60, d_up=date.time.value+15*60)], on=.(date.time.event>=d_dn, date.time.event<=d_up), event]]
Вот как выглядит результат. Мы видим, что у нас есть один пик значения флуоресценции для каждого события A, B и C, а остальные значения флуоресценции имеют NA в качестве события:
ggplot(values, aes(date.time.value, fluor,col=event)) + geom_point()
Реальный пример:
Мне удалось связать два набора данных, раскрасив значения флуоресценции, которые происходят за несколько минут до или несколько минут после события. Вот как выглядит результат:
Что мне не хватает:
- Я хотел бы определить “пики”, чтобы в моем упрощенном примере все зеленые значения флуоресценции события B принадлежали конкретному “пикам номер x”. В настоящее время невозможно отличить значения флуоресценции одного и того же события, но из разных пиков, потому что у меня есть только наблюдения флуоресценции с соответствующей переменной “событие”.
- В упрощенном примере вы можете увидеть (преувеличенно), что довольно много высоких значений флуоресценции считаются NA, хотя их высокая величина, вероятно, вызвана событием. Поэтому я ищу лучший способ связать значения флуоресценции с событиями, чем просто говорить “15 минут до или 15 минут после”.
Я почти уверен, что должен быть какой-то пакет R, который специально создан для моей проблемы здесь, но я просто не могу понять, какой именно…
Кажется, вы ищете механизм кластеризации для ваших данных последовательности событий на основе меры несходства/расстояния. Я бы порекомендовал вам изучить пакет TraMineR.
Ответ или решение
Для решения вашей задачи по анализу изменяемых значений флуоресценции в зависимости от известных событий, вам действительно могут помочь методы кластеризации и пакет R, предназначенные для временных рядов и анализа событий.
Шаг 1: Определение "пиков" и кластеризация
Сначала мы можем определить пики на основе значений флуоресценции и времени их появления. Для этого можно воспользоваться пакетом pracma
, который содержит функцию для определения пиков. В вашем случае, мы можем выделить пики на основе значения флуоресценции, а затем связать их с событиями.
Пример кода:
library(data.table)
library(pracma)
# Генерация флуоресценции и событий
set.seed(10)
values <- data.table(date.time.value = seq(ymd_hms("2018-01-01 00:00:00"), by = "min", length.out = 200),
fluor = 5 * sin(seq(0, 20, length.out = 200)) + (abs(rnorm(200, 6, 1)) + 2))
events <- data.table(event = c("A", "B", "C"),
date.time.event = c(ymd_hms("2018-01-01 00:20:00"),
ymd_hms("2018-01-01 01:20:00"),
ymd_hms("2018-01-01 02:20:00")))
# Поиск пиков
peaks <- findpeaks(values$fluor)
# Получение индексов пиков
peak_indices <- peaks[, 2]
# Назначение пиковой категории
values[, peak_number := NA]
values[peak_indices, peak_number := seq_along(peak_indices)]
# Визуализация
ggplot(values, aes(date.time.value, fluor, col = as.factor(peak_number))) + geom_point()
Шаг 2: Расширение интервала времени
Для того чтобы улучшить вашу стратегию связывания значений флуоресценции с событиями, вы можете рассмотреть использование более сложных методов, таких как дальность или даже машинное обучение с использованием методов временных рядов для углубленного анализа зависимости. Например, можно использовать zoo
или xts
для анализа временных рядов и интерполяции значений:
# Использование zoo для обработки временных рядов
library(zoo)
# Присоединение событий к данным с помощью временных рядов
values_zoo <- zoo(values$fluor, order.by = values$date.time.value)
# Управление временными рядами с заданными интервалами
for (i in 1:nrow(events)) {
values_zoo[events$date.time.event[i] + (-15*60):(15*60)] <-
replace(values_zoo[events$date.time.event[i] + (-15*60):(15*60)],
is.na(values_zoo[events$date.time.event[i] + (-15*60):(15*60)]),
events$event[i])
}
С использованием вышеописанных методов вы сможете определить, к какому событию относится каждое значение флуоресценции, а также улучшить качество вашего анализа.
Заключение
Для вашего задания можно использовать такие пакеты, как pracma
для поиска пиков, zoo
для интерполяции временных рядов и ggplot2
для визуализации. Эти инструменты позволят более глубоким образом анализировать и связывать ваши данные с событиями.