如何获取DataFrame中各total_turn_angle对应的T的起止值?
解决方案:按分组提取角度值对应的T区间起止值
问题描述
现有包含compID、total_turn_angle、T三个变量的R DataFrame:
compID为唯一分组标识total_turn_angle的有效值仅出现在对应连续T区间的中点行,其余行值为NA- 需要按
compID分组,提取每个有效total_turn_angle对应的T区间的起始值和结束值
示例输入DataFrame:
structure(list(compID = c("d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27", "d0627-Cc010-27"), total_turn_angle = c(NA, NA, NA, NA, NA, -6.45412963, NA, NA, NA, NA, NA, NA, NA, NA, NA, -6.434909322, NA, NA, NA, NA), T = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L)), class = "data.frame", row.names = c(NA, -20L))
期望输出:
compID total_turn_angle start end d0627-Cc010-27 -6.454130 1 10 d0627-Cc010-27 -6.434909 35 44
实现方案
方法1:使用dplyr包(适合常规数据处理)
library(dplyr) df %>% group_by(compID) %>% # 为每个连续T区间创建分组标记:遇到非NA角度值则递增分组ID mutate(interval_group = cumsum(!is.na(total_turn_angle))) %>% filter(interval_group > 0) %>% # 过滤无有效角度的区间 group_by(compID, interval_group) %>% summarise( total_turn_angle = first(na.omit(total_turn_angle)), # 提取区间对应的角度值 start = min(T), end = max(T), .groups = "drop" ) %>% select(-interval_group) # 移除临时分组标记
方法2:使用data.table包(适合大型数据集,效率更高)
library(data.table) setDT(df) df[, .(total_turn_angle = na.omit(total_turn_angle)[1], start = min(T), end = max(T)), by = .(compID, interval_group = cumsum(!is.na(total_turn_angle))) ][interval_group > 0, !"interval_group"] # 过滤无效分组并移除标记
核心逻辑说明
- 利用
cumsum(!is.na(total_turn_angle))生成区间分组ID:每遇到一个非NA的total_turn_angle,分组ID递增,后续同属一个连续T区间的行共享该ID。 - 通过分组聚合,提取每个区间的最小
T(起始值)、最大T(结束值),以及对应的有效角度值。 - 两种方法均支持多
compID的批量处理,自动保留分组对应关系。
内容的提问来源于stack exchange,提问作者Kaye11
相关产品推荐
相关产品推荐

