基于tidyverse对按日期分组的大型R数据框执行线性插值
R分组按日线性插值解决方案
我需要在R的数据框中,按date_index分组对数值做线性插值,基于f_date补全每日的数据。每个date_index组内的f_date数量不固定,得每个组单独插值后再合并成完整数据框。我写了代码但分组插值逻辑没生效,示例数据和代码如下:
原始代码(未生效)
library(tidyverse) library(lubridate) df <- data.frame("date_index"=c("20230104", "20230104", "20230104", "20230106", "20230106", "20230106"), "f_date"=c("20230201", "20230203", "20230210", "20230201", "20230203", "20230210"), "value" = c(1.50, 2.00, 3.25, 4.00, 3.00, 2.50)) %>% mutate(date_index=ymd(date_index), f_date=ymd(f_date)) df %>% group_by(date_index) %>% arrange(f_date) date_first <- first(df$f_date) date_last <- last(df$f_date) ApproxFun <- approxfun(x = df$f_date, y = df$value) date_seq <- seq.Date(ymd(date_first), ymd(date_last), by = 1) LinearFit <- ApproxFun(date_seq) # the interpolated dataframe dfi <- data.frame(f_date = date_seq, value = LinearFit)
期望输出
date_index f_date value 2023-01-04 2023-02-01 1.50 2023-01-04 2023-02-02 1.75 2023-01-04 2023-02-03 2.00 2023-01-04 2023-02-04 2.18 2023-01-04 2023-02-05 2.36 2023-01-04 2023-02-06 2.54 2023-01-04 2023-02-07 2.71 2023-01-04 2023-02-08 2.89 2023-01-04 2023-02-09 3.07 2023-01-04 2023-02-10 3.25 2023-01-06 2023-02-01 4.00 2023-01-06 2023-02-02 3.50 2023-01-06 2023-02-03 3.00 2023-01-06 2023-02-04 2.93 2023-01-06 2023-02-05 2.86 2023-01-06 2023-02-06 2.79 2023-01-06 2023-02-07 2.71 2023-01-06 2023-02-08 2.64 2023-01-06 2023-02-09 2.57 2023-01-06 2023-02-10 2.50
正确解决方案代码
library(tidyverse) library(lubridate) # 加载并预处理原始数据 df <- data.frame( date_index = c("20230104", "20230104", "20230104", "20230106", "20230106", "20230106"), f_date = c("20230201", "20230203", "20230210", "20230201", "20230203", "20230210"), value = c(1.50, 2.00, 3.25, 4.00, 3.00, 2.50) ) %>% mutate(date_index = ymd(date_index), f_date = ymd(f_date)) # 分组执行插值并合并结果 df_interpolated <- df %>% group_by(date_index) %>% # 生成当前组内完整的每日日期序列 complete(f_date = seq.Date(min(f_date), max(f_date), by = "day")) %>% # 对当前组的value做线性插值 mutate(value = approx(x = f_date, y = value, xout = f_date)$y) %>% ungroup() # 输出结果 print(df_interpolated)
问题说明
原始代码的核心问题是分组后未在组内执行插值逻辑:你只是做了分组和排序,但后续的first()、last()、approxfun()都是基于整个数据集计算的,完全没有用到分组后的子集,导致分组失效。
正确的做法是利用group_by()结合complete()生成每个组内的完整日期序列,再用approx()在组内完成线性插值,最后ungroup()合并所有组的结果,得到符合预期的数据集。
内容的提问来源于stack exchange,提问作者Calvin
相关产品推荐
相关产品推荐

