R语言根据列值匹配从多个数据框取值填充目标数据框
R语言按处理组+深度匹配填充盐度值实现方案
前置准备
首先修正示例中处理组深度-盐度对照表的语法错误,统一所有对照表格式:
- 所有处理组对照表命名遵循
tr+处理位点去小数点规则,例如处理位点1.1对应表名tr11,2.3对应表名tr23 - 所有对照表列名统一为
Depth、Salinity,不要携带组号后缀 - 对照表深度列需覆盖1-40全部整数,无缺失值
正确的单处理组对照表生成示例:
# 处理组1.1对照表示例 Depth11 <- 1:40 Salinity11 <- sample(1:40, size = 40, replace = TRUE) tr11 <- data.frame(Depth = Depth11, Salinity = Salinity11)
方案1:循环批量填充(优先推荐,适配任意数量处理组)
直接遍历主表每一行,自动匹配对应处理组的盐度值填充,代码如下:
for (i in 1:nrow(dftot)) { # 拼接当前行对应的处理组表名 tr_table_name <- paste0("tr", gsub("\\.", "", dftot$Treatment[i])) # 读取对应处理组对照表 current_tr <- get(tr_table_name) # 按深度匹配盐度并填充 dftot$Salinity[i] <- current_tr$Salinity[current_tr$Depth == dftot$Depth[i]] }
运行完成后dftot的Salinity列会自动填充完成。
方案2:逐组手动填充(适合处理组数量较少场景)
如果处理组总数不多,可以逐组运行匹配代码,无需编写循环:
# 填充处理组1.1的盐度 dftot$Salinity[dftot$Treatment == "1.1"] <- tr11$Salinity[match( dftot$Depth[dftot$Treatment == "1.1"], tr11$Depth )] # 填充处理组1.2的盐度,替换对应组名、表名即可 dftot$Salinity[dftot$Treatment == "1.2"] <- tr12$Salinity[match( dftot$Depth[dftot$Treatment == "1.2"], tr12$Depth )] # 剩余处理组参照上述格式依次运行即可
方案3:大表合并一次性匹配(适合百万行级大数据量场景,性能最优)
如果主表数据量极大,循环运行速度慢,可以先把所有处理组的对照表合并为一张总表,再做一次性双列匹配:
# 获取当前环境中所有处理组对照表的对象名 tr_list_name <- ls(pattern = "^tr") # 批量合并所有处理组对照表,补充Treatment列 all_tr_table <- do.call(rbind, lapply(tr_list_name, function(tb_name){ tb <- get(tb_name) # 从表名还原对应的Treatment值,例如tr11还原为"1.1" tb$Treatment <- gsub("(\\d)(\\d)$", "\\1.\\2", gsub("^tr", "", tb_name)) tb })) # 按Treatment+Depth双列一次性匹配填充 dftot$Salinity <- all_tr_table$Salinity[match( paste(dftot$Treatment, dftot$Depth), paste(all_tr_table$Treatment, all_tr_table$Depth) )]
内容的提问来源于stack exchange,提问作者Laura Schefold
相关产品推荐
相关产品推荐

