基于样条插值(spline)实现数据框列间逐行插值
解决方案
方法思路
- 提取原数据列名中的数字(如
x1对应1,x3对应3),作为插值的x坐标; - 逐行对数值列进行样条插值,生成从1到15所有整数点的插值结果;
- 将插值结果与原
dates列合并,得到目标数据框。
代码实现(Tidyverse版本)
library(tidyverse) # 原数据 df <- data.frame(dates = c("2020-12-31", "2021-01-31"), x1 = c(0.50, 0.60), x3 = c(1.00, 0.90), x5 = c(1.50, 1.80), x7 = c(2.00, 2.10), x12 = c(2.50, 2.60), x15 = c(3.00, 3.10)) # 提取列名对应的数字 col_nums <- as.integer(sub("x", "", names(df)[-1])) # 定义单行插值函数 interpolate_row <- function(row) { y_vals <- row[-1] # 样条插值生成1到15的所有整数点结果 spline_res <- spline(x = col_nums, y = y_vals, xout = 1:15) # 命名结果为x1到x15 set_names(spline_res$y, paste0("x", spline_res$x)) } # 逐行插值并合并结果 df_inter <- df %>% mutate(interpolated = pmap(., ~interpolate_row(c(...)))) %>% unnest_wider(interpolated) # 查看结果 print(df_inter)
代码实现(Base R版本,无需加载额外包)
# 原数据 df <- data.frame(dates = c("2020-12-31", "2021-01-31"), x1 = c(0.50, 0.60), x3 = c(1.00, 0.90), x5 = c(1.50, 1.80), x7 = c(2.00, 2.10), x12 = c(2.50, 2.60), x15 = c(3.00, 3.10)) # 提取列名对应的数字 col_nums <- as.integer(sub("x", "", names(df)[-1])) # 初始化结果数据框 df_inter <- data.frame(dates = df$dates) # 遍历1到15的每个点,逐行插值填充 for (x in 1:15) { df_inter[[paste0("x", x)]] <- apply(df[, -1], 1, function(row) { spline(x = col_nums, y = row, xout = x)$y }) } # 查看结果 print(df_inter)
说明
- 两个版本均使用R内置的
spline()函数,默认采用FMM样条插值方法; - 代码支持数百行数据的批量处理,效率满足常规需求;
- 若原数据存在缺失值(NA),需先处理缺失值再执行插值,否则
spline()会报错。
内容的提问来源于stack exchange,提问作者RSX
相关产品推荐
相关产品推荐

