基于条件匹配两个DataFrame并替换值?现有R代码存在问题求优化
解决方案
首先注意到regions中的start和end是字符类型,而value中的rf1、rt1等是整数/数值类型,第一步需要统一数据类型,否则无法正确匹配。
方法一:使用dplyr(推荐,代码更清晰)
library(dplyr) # 转换regions的start和end为整数类型 regions <- regions %>% mutate(start = as.integer(start), end = as.integer(end)) # 执行匹配、替换和过滤 result <- value %>% # 匹配rf1-rt1与start-end,获取对应的V2、V3 left_join(regions, by = c("rf1" = "start", "rt1" = "end"), suffix = c("", "_1")) %>% rename(rf1_new = V2, rt1_new = V3) %>% # 匹配rf2-rt2与start-end,获取对应的V2、V3 left_join(regions, by = c("rf2" = "start", "rt2" = "end"), suffix = c("", "_2")) %>% rename(rf2_new = V2, rt2_new = V3) %>% # 过滤掉任一组合不匹配的行(即存在NA的行) filter(!is.na(rf1_new) & !is.na(rf2_new)) %>% # 替换原列并整理结果 select(rf1 = rf1_new, rt1 = rt1_new, rf2 = rf2_new, rt2 = rt2_new) print(result)
方法二:使用base R
# 转换regions的start和end为整数类型 regions$start <- as.integer(regions$start) regions$end <- as.integer(regions$end) # 第一次匹配rf1-rt1 match1 <- merge(value, regions, by.x = c("rf1", "rt1"), by.y = c("start", "end"), all.x = TRUE) match1 <- match1[, c("rf1", "rt1", "rf2", "rt2", "V2", "V3")] names(match1)[5:6] <- c("rf1_new", "rt1_new") # 第二次匹配rf2-rt2 match2 <- merge(match1, regions, by.x = c("rf2", "rt2"), by.y = c("start", "end"), all.x = TRUE) match2 <- match2[, c("rf1_new", "rt1_new", "V2", "V3")] names(match2)[3:4] <- c("rf2_new", "rt2_new") # 过滤不匹配的行 result <- match2[!is.na(match2$rf1_new) & !is.na(match2$rf2_new), ] names(result) <- c("rf1", "rt1", "rf2", "rt2") print(result)
结果说明
运行上述代码后,只有同时满足两个匹配条件的行会被保留,并且原rf1/rt1、rf2/rt2会被替换为对应的V2/V3值。针对你提供的示例数据,最终结果只会保留原value的第二行(行名1112L),因为只有该行的两个组合都能在regions中匹配到。
内容的提问来源于stack exchange,提问作者Rhea Bedi
相关产品推荐
相关产品推荐

