时间序列数据事件前后行提取及中心化时序图绘制技术问题
解决时间序列中状态 onset 前后时序分组绘图问题
目标
从时间序列数据框df中,绘制特定状态(如状态A)每次出现时,其onset(起始行)前后指定时间点的图形。x轴以0为中心,事件前的时间点为负值,事件后的为正值,原理与**刺激时间直方图(peristimulus time histogram)**一致。
数据说明
我们有一组状态持续时长可变的时间序列数据,先通过游程编码(run length encoding)确定各状态的起止,再用以下函数提取状态A onset前1行、后2行的数据,得到extracted数据集:
# 数据构建 df <- data.frame( state = c("A","A","A","A","A","B","A","A","X","Y","Z","A","A","A","B","A","A"), start = c("start","NA","NA","NA","NA","NA","start","NA","NA","NA","NA","start","NA","NA","NA","start","NA"), rleGroup = c("1","1","1","1","1","2","3","3","4","5","6","7","7","7","8","9","9"), data = runif(17) ) %>% mutate(original_row = row_number()) %>% # 添加原始行号用于后续匹配 tidyr::unite(stateStart, c(state,start), sep = ".", remove = FALSE) # 提取函数 extract.with.context <- function(x, colname, rows, after = 0, before = 0) { match.idx <- which(x[[colname]] %in% rows) span <- seq(from = -before, to = after) extend.idx <- c(outer(match.idx, span, `+`)) extend.idx <- Filter(function(i) i > 0 & i <= nrow(x), extend.idx) extend.idx <- sort(unique(extend.idx)) return(x[extend.idx, , drop = FALSE]) } extracted = extract.with.context(x=df, colname="stateStart", rows=c("A.start"), after = 2, before = 1)
待解决问题
- 创建唯一
plotGroup标识:为每个包含A onset前1行、后2行的分组生成唯一标识,现有尝试未得到预期效果。 - 创建中心化
span计数器:生成以0为中心的计数器,标记A onset前1行(值为-1)、起始行(值为0)、后2行(值为1、2)。
解决方案
我们可以基于原数据中A onset的位置,为提取出的每条数据匹配对应的分组和span值:
library(dplyr) library(purrr) # 获取所有A onset在原数据中的位置 onset_indices <- which(df$stateStart == "A.start") before_n <- 1 after_n <- 2 # 生成每个onset对应的分组和span映射表 group_span_map <- map_dfr(seq_along(onset_indices), function(group_id) { onset_row <- onset_indices[group_id] # 计算该onset覆盖的行范围 target_rows <- seq(onset_row - before_n, onset_row + after_n) # 过滤掉超出数据框范围的无效行 valid_rows <- target_rows[target_rows >= 1 & target_rows <= nrow(df)] # 生成对应的中心化span值 span_values <- seq(-before_n, after_n)[seq_along(valid_rows)] tibble( original_row = valid_rows, plotGroup = group_id, span = span_values ) }) # 将分组和span信息合并到extracted数据集中 extracted <- extracted %>% left_join(group_span_map, by = "original_row")
关键说明
- 通过保留原始行号,确保提取后的数据能精准匹配到对应的onset分组
- 为每个onset生成独立的
plotGroup编号,保证分组唯一性 - 按onset位置生成中心化的
span值,直接对应相对时间点
最终绘图
使用ggplot绘制各分组的时序图:
library(ggplot2) ggplot(data=extracted, aes(x=span, y = data, group = plotGroup)) + geom_line() + labs(x = "相对于A onset的时间点", y = "数据值")
内容的提问来源于stack exchange,提问作者redatoms
相关产品推荐
相关产品推荐

