如何在分组数据框的时间点间按n步实现线性插值?
R语言实现分组时间点间的线性插值
核心思路
- 按
GroupVar分组,确保每组内时间点顺序正确 - 对每组内相邻的原始时间点,生成指定步数的线性插值中间点
- 合并原始数据与插值结果,标记是否为插值生成的点
可复用代码实现
下面是封装好的函数,参数n为每个时间区间的插值步数(示例中为2步):
library(dplyr) library(tidyr) interpolate_timepoints <- function(data, n = 2) { # 为每组时间点分配顺序索引,保证排序逻辑正确 data <- data %>% group_by(GroupVar) %>% mutate(time_order = row_number()) %>% ungroup() # 生成每组内相邻时间点的配对数据 paired_data <- data %>% group_by(GroupVar) %>% mutate( next_time_order = lead(time_order), next_Value = lead(Value), next_timepoint = lead(timepoint) ) %>% filter(!is.na(next_time_order)) %>% ungroup() # 逐对生成插值数据 interpolated_list <- lapply(1:nrow(paired_data), function(i) { row <- paired_data[i, ] # 生成插值数值,包含起点但排除终点(避免与原始终点重复) interp_values <- approx( x = c(row$time_order, row$next_time_order), y = c(row$Value, row$next_Value), n = n + 2 )$y[-n-2] # 生成插值时间标识,采用比例形式体现等步长 interp_timepoints <- paste0("t", round(seq(1/(n+1), n/(n+1), 1/(n+1)), 2)) # 构造插值数据框 data.frame( GroupVar = row$GroupVar, timepoint = interp_timepoints, Value = round(interp_values[-1], 1), # 移除与起点重复的第一个值 isInterp = 1, time_order = seq(row$time_order + 1/(n+1), row$next_time_order - 1/(n+1), 1/(n+1)) ) }) # 合并原始数据(标记为非插值点)与插值数据 original_with_flag <- data %>% mutate(isInterp = 0) %>% select(GroupVar, timepoint, Value, isInterp, time_order) result <- bind_rows(original_with_flag, do.call(rbind, interpolated_list)) %>% arrange(GroupVar, time_order) %>% select(-time_order) # 移除辅助排序列 return(result) } # 测试示例数据 data <- data.frame( GroupVar = c("A", "A", "A", "B", "B", "B"), timepoint = c("Start", "t1", "End", "Start", "t1", "End"), Value = c(100, 50, 10, 100, 40, 15) ) # 调用函数,设置每个区间2步插值 data2 <- interpolate_timepoints(data, n = 2) print(data2)
关键细节说明
time_order列:避免timepoint字符串排序逻辑错误,确保插值按正确时间顺序进行approx函数:利用R基础包实现线性插值,通过n参数灵活控制插值步数isInterp列:0代表原始观测点,1代表插值生成点- 时间标识:示例采用
t+比例格式,你可根据需求修改interp_timepoints的生成规则
内容的提问来源于stack exchange,提问作者Yolo_chicken
相关产品推荐
相关产品推荐

