如何通过循环按正则匹配对文件对执行Full Join操作
问题分析与解决方案
先梳理你原代码里的核心问题:
- 双层循环完全冗余,
average_list2和full_list2是按文件名顺序一一对应的,单循环即可处理 dplyr::full_join()缺少必须的两个数据集参数,原代码只写了关联条件,没有指定要合并的对象- 合并结果未存入列表且
write.table放在循环外,最终只会生成最后一组的合并文件 - 列名赋值时变量名写错:
new_col_names应改为定义好的new_colnames,new_col_names2对应new_colnames2
修正后的完整代码
第一步:修正列名标准化代码
library(data.table) library(dplyr) # 读取并标准化averageLD文件列名 average_list <- lapply(Sys.glob("ld_interval/averageLD_*.txt"), fread) new_colnames <- c("sec", "r2") average_list2 <- lapply(average_list, set_names, new_colnames) # 修正变量名错误 # 读取并标准化fullLD文件列名 full_list <- lapply(Sys.glob("ld_interval/fullLD*.txt"), fread) new_colnames2 <- c("V1", "V2", "V3", "V4", "V5", "V6", "V7", "sec", "r2") full_list2 <- lapply(full_list, set_names, new_colnames2) # 修正变量名错误
第二步:执行配对合并并输出文件
# 初始化列表存储所有合并结果(可选,若需要保留全部结果) full_join_results <- list() # 单循环处理每一对对应文件 for (i in seq_along(average_list2)) { # 取出对应位置的两个数据集执行full_join merged_data <- dplyr::full_join( x = average_list2[[i]], y = full_list2[[i]], by = "sec" # 按sec列关联,重复的r2列会自动添加后缀区分 ) # 将合并结果存入列表 full_join_results[[i]] <- merged_data # 写出当前合并后的文件 write.table( merged_data, file = paste0("ld_interval/fulljoina_", i, ".txt"), quote = FALSE, sep = "\t", row.names = FALSE, col.names = FALSE ) }
额外优化说明
- 由于两个数据集都有
r2列,合并后会自动命名为r2.x(来自averageLD)和r2.y(来自fullLD),如果需要自定义后缀,可添加suffix参数:
merged_data <- dplyr::full_join( x = average_list2[[i]], y = full_list2[[i]], by = "sec", suffix = c("_average", "_full") )
- 若担心
Sys.glob读取的文件顺序混乱(比如1-10的文件会被读成1,10,2...),可手动提取文件名中的数字排序:
# 修正averageLD文件读取顺序 average_files <- Sys.glob("ld_interval/averageLD_*.txt") average_files_sorted <- average_files[order(as.integer(sub("averageLD_(\\d+).txt", "\\1", basename(average_files))))] average_list <- lapply(average_files_sorted, fread) # 同理修正fullLD文件读取顺序 full_files <- Sys.glob("ld_interval/fullLD*.txt") full_files_sorted <- full_files[order(as.integer(sub("fullLD(\\d+).txt", "\\1", basename(full_files))))] full_list <- lapply(full_files_sorted, fread)
内容的提问来源于stack exchange,提问作者Johanna Ramirez
相关产品推荐
相关产品推荐

