基于R语言现有数据框z1连续两行生成新数据框z2的实现方法
解决R语言数据框插值生成新数据框的问题
我来帮你搞定这个需求!首先我们明确核心目标:在每个time分组内,对连续两行的roi和area做10个点的线性插值,最终生成总行数为10*nrow(z1)的新数据框z2。下面分两种常用方法实现,你可以根据习惯选择:
方法一:dplyr(tidyverse风格)
先加载dplyr包,同时设置随机种子让area的随机结果可复现:
library(dplyr) set.seed(123) # 固定随机数种子,保证每次运行结果一致 z1 <- data.frame(time=as.factor(rep(0.5:9.5,times=rep(c(9,10,8,11,12),2))), roi= rep(c(1:9,1:10,1:8,1:11,1:12),2), area=runif(100, 5.0, 7.5))
接下来是核心的插值与拼接步骤:
z2 <- z1 %>% group_by(time) %>% # 按time分组,确保仅在同一时间区间内插值 group_modify(function(df, .group) { # 遍历当前分组的每一对连续行,生成10个插值点 interp_rows <- lapply(1:(nrow(df)-1), function(i) { tibble( time = .group$time, roi = seq(df$roi[i], df$roi[i+1], length.out = 10), area = seq(df$area[i], df$area[i+1], length.out = 10) ) }) %>% bind_rows() # 把当前分组的最后一行复制10次,凑够每个分组10倍于原行数的总行数 final_rows <- tibble( time = .group$time, roi = rep(df$roi[nrow(df)], 10), area = rep(df$area[nrow(df)], 10) ) # 合并插值行和最后一行的复制行 bind_rows(interp_rows, final_rows) }) %>% ungroup() # 取消分组,回到普通数据框格式
方法二:data.table(高效处理大数据)
如果你的数据量较大,data.table的运行速度会更有优势,代码如下:
library(data.table) set.seed(123) z1 <- data.frame(time=as.factor(rep(0.5:9.5,times=rep(c(9,10,8,11,12),2))), roi= rep(c(1:9,1:10,1:8,1:11,1:12),2), area=runif(100, 5.0, 7.5)) setDT(z1) # 将普通数据框转换为data.table格式 z2 <- z1[, { df <- .SD # 生成连续行对的插值列表 interp_list <- lapply(1:(.N-1), function(i) { data.table( time = time[1], roi = seq(df$roi[i], df$roi[i+1], length.out = 10), area = seq(df$area[i], df$area[i+1], length.out = 10) ) }) # 加上最后一行的10次复制,合并所有结果 rbindlist(c(interp_list, list(data.table( time = time[1], roi = rep(df$roi[.N], 10), area = rep(df$area[.N], 10) )))) }, by = time]
结果验证
你可以用nrow(z2)检查行数,应该正好是10*nrow(z1)即1000行;也可以筛选某个time分组(比如filter(z2, time == "0.5"))查看行数是否为90行,验证是否符合预期。
内容的提问来源于stack exchange,提问作者Hoang Le
相关产品推荐
相关产品推荐

