R语言按相同plots字段与最近日期合并两个data.frame及报错修复
错误原因与原生R代码修复
你写的代码存在两个问题:
- 括号匹配错误:
intersect()的闭合括号被放在了自定义函数后面,导致lapply没有接收到第二个遍历执行的函数参数,触发报错 - 列名拼写错误:两个数据框的日期列名为
dates,代码中误写为date
修复后的代码如下:
df1.2 <- lapply(intersect(df1$plots, df2$plots), function(id) { d1 <- subset(df1, plots == id) d2 <- subset(df2, plots == id) d1$indices <- sapply(d1$dates, function(d) which.min(abs(d2$dates - d))) d2$indices <- 1:nrow(d2) merge(d1, d2, by = c('plots', 'indices')) }) # 合并列表为数据框,调整列名得到目标结果 result <- do.call(rbind, df1.2) result <- result[, c("plots", "dates.x", "TargetValues")] colnames(result) <- c("plots", "dates", "Values") # 按原df1顺序排列 result <- result[order(match(result$dates, df1$dates)), ]
运行后即可得到你期望的输出结果。
更高效的推荐方案:data.table滚动连接
如果数据量较大,用data.table的滚动连接性能会比逐行遍历高很多,代码也更简洁:
library(data.table) # 转换为data.table格式,按plots和dates排序 setDT(df1) setDT(df2) setorder(df1, plots, dates) setorder(df2, plots, dates) # 按plots分组,滚动匹配最近日期 result <- df2[df1, on = .(plots, dates), roll = "nearest"] # 调整列名得到最终结果 setnames(result, "TargetValues", "Values") result <- result[, .(plots, dates, Values)]
该方案底层是C实现的匹配逻辑,处理上万行以上数据的速度优势非常明显。
内容的提问来源于stack exchange,提问作者Maike
相关产品推荐
相关产品推荐

