基于Skov方法检测海豚幽灵血统:私有等位基因定位与统计需求
嘿,这是调整后的R代码,既保留了你原本的区间统计功能,又新增了输出每个区间内私有等位基因具体位置的功能:
首先,我们先确保私有等位基因的数据保留关键列,再为每个位置分配区间,最后按区间汇总数量和位置:
# 1. 识别ind0的私有等位基因位置(排除N的情况) res1 <- df1[ rowSums(df1$ind0 == df1[, -c(1:3)]) == 0 & apply(df1[, -c(1:3)], 1, function(i) length(unique(i[i != "N"]))) == 1, c("scaffold", "pos", "ind0") # 保留需要的列,方便后续关联区间和位置 ] # 2. 为每个私有等位基因分配1000bp区间 # 这里可以根据你的参考基因组最大位置动态调整上限,更灵活 max_pos <- ceiling(max(df1$pos)/1000)*1000 res1$interval <- cut( res1$pos, breaks = seq(0, max_pos, by = 1000), include.lowest = TRUE, # 确保0位置被正确包含在第一个区间 dig.lab = 10 # 避免区间标签被科学计数法显示,可读性更强 ) # 3. 按区间汇总(推荐用dplyr,代码更简洁直观) # 如果没安装dplyr先运行:install.packages("dplyr") library(dplyr) interval_summary <- res1 %>% group_by(scaffold, interval) %>% # 多scaffold时必须按scaffold+区间分组,避免跨scaffold混淆 summarise( private_allele_count = n(), private_allele_positions = paste(pos, collapse = ", ") ) %>% ungroup() # 4. 查看结果或导出到文件 print(interval_summary) write.csv(interval_summary, "private_allele_interval_summary.csv", row.names = FALSE)
如果不想用dplyr,也可以用base R实现相同功能:
# base R版本的汇总逻辑 interval_summary_base <- aggregate( pos ~ scaffold + interval, data = res1, FUN = function(x) list( count = length(x), positions = paste(x, collapse = ", ") ) ) # 展开list类型的列,转换成标准数据框 interval_summary_base <- do.call(data.frame, interval_summary_base) names(interval_summary_base) <- c("scaffold", "interval", "private_allele_count", "private_allele_positions")
几个注意点:
- 如果你的数据集包含多个scaffold,一定要按scaffold+区间分组,不然不同scaffold的同数值区间会被错误合并;
- 动态计算
max_pos可以避免手动设置上限的麻烦,确保覆盖所有位点; - 原代码的私有等位基因判断逻辑是对的:确保ind0的等位基因和其他所有个体都不同,且其他个体的有效等位基因(非N)完全一致,符合你的检测需求。
内容的提问来源于stack exchange,提问作者mariels17
相关产品推荐
相关产品推荐

