基于亲本列值逐行重编码子代遗传数据的R语言求助
问题分析与解决方案
原代码的核心问题是全局修改了整个Test数据框的元素,而非仅处理当前行的子代数据,同时逻辑未针对每行的双亲值做逐元素对比,导致编码混乱甚至出现NA。
原代码错误点
Test[Test[i, ] == "A"] <- "a"这行代码会修改整个Test中所有等于"A"的单元格,而非第i行里的"A",后续循环会覆盖之前的修改,最终导致结果错误。- 逻辑仅判断了P1或P2等于"A"的情况,未针对每行不同的P1/P2值适配,也未实现"h"的编码逻辑。
解决方案一:修正循环(直观易懂)
先创建空结果容器,逐行逐列对比子代与双亲值,避免全局修改:
# 初始化结果矩阵,结构与Test一致 result <- matrix(NA, nrow = nrow(Test), ncol = ncol(Test)) colnames(result) <- colnames(Test) # 逐行处理 for (i in 1:nrow(Test)) { # 获取当前行的双亲值 p1 <- Parents[i, 1] p2 <- Parents[i, 2] # 逐列处理子代元素 for (j in 1:ncol(Test)) { val <- Test[i, j] if (val == p1) { result[i, j] <- "a" } else if (val == p2) { result[i, j] <- "b" } else if (val %in% c(paste0(p1, p2), paste0(p2, p1))) { # 假设"同时包含两者"是指杂合子(如P1=A、P2=T,子代是AT/TA),可根据实际数据格式调整 result[i, j] <- "h" } # 若有其他情况,可添加else分支定义处理方式(如保留原值或标记为NA) } } # 转换为数据框(可选) result_df <- as.data.frame(result)
解决方案二:向量化操作(高效推荐)
R中循环效率较低,300+行数据用向量化函数处理更快:
# 定义编码函数:输入一行子代数据、一行双亲数据,返回编码后的行 recode_row <- function(test_row, parent_row) { p1 <- parent_row[1] p2 <- parent_row[2] sapply(test_row, function(x) { if (x == p1) { "a" } else if (x == p2) { "b" } else if (x == paste0(p1, p2) || x == paste0(p2, p1)) { "h" } else { NA # 其他情况默认设为NA,可按需修改 } }) } # 逐行应用函数,转置后恢复数据框结构 result_df <- t(mapply(recode_row, split(Test, 1:nrow(Test)), split(Parents, 1:nrow(Parents)))) # 转换为数据框并保留列名 result_df <- as.data.frame(result_df) colnames(result_df) <- colnames(Test)
注意事项
- 若"同时包含两者"的格式不是杂合子字符串(比如子代同时存在P1和P2的标记),需要修改
else if里的判断逻辑,匹配你的实际数据格式。 - 若存在双亲值相同的行,可添加判断分支统一编码(比如都标为"a"或其他标记)。
内容的提问来源于stack exchange,提问作者MWhyte
相关产品推荐
相关产品推荐

