如何按滑动窗口汇总data.table中各状态标志的出现次数
如何按滑动窗口汇总data.table中各状态标志的出现次数
我来帮你搞定这个滑动窗口统计状态码次数的需求,咱们一步步来实现:
第一步:准备示例数据
先把你提供的示例代码整理好,确保数据和滑动窗口都能正常生成:
library(data.table) # 生成状态码列表 status_codes <- c() for (a in c(1, 2, 3, 6, 9)) { for (b in c(1, 2, 3, 6, 9)) { status_code <- a * 10 + b status_codes <- c(status_codes, status_code) } } # 创建示例data.table set.seed(123666) gt_diff <- data.table( chrom = rep(1, 1000), pos = seq(1, 1000), sample = sample(status_codes[1:9], 1000, replace = TRUE), sample1 = sample(status_codes, 1000, replace = TRUE), sample2 = sample(status_codes, 1000, replace = TRUE) ) # 生成滑动窗口 slide_window <- function(start, end, window, step){ ranges = data.frame(start=integer(), stop=integer()) i = start while(i <= end){ stop = min(i + window - 1, end) ranges[nrow(ranges) + 1, ] = c(i, stop) i = i + step } return(ranges) } ranges <- slide_window(min(gt_diff$pos), max(gt_diff$pos), windows = 10, step = 1)
第二步:核心处理流程
这里我们用data.table的高效操作来实现,主要分为转长格式、区间匹配、分组统计三个步骤:
1. 将宽格式数据转为长格式
把所有样本列的状态码整合到一列里,方便统一处理:
# 转长格式,保留chrom和pos,把所有以sample开头的列合并 gt_long <- melt(gt_diff, id.vars = c("chrom", "pos"), measure.vars = patterns("^sample"), # 匹配所有样本列 variable.name = "sample_col", value.name = "status_code")
2. 匹配每个位置对应的滑动窗口
用data.table的foverlaps函数快速完成位置和窗口的区间匹配:
# 把ranges转为data.table并添加chrom列(和原数据保持一致) setDT(ranges)[, chrom := 1] # 设置键用于区间匹配 setkey(ranges, chrom, start, stop) # 给每个位置创建自身的区间(start和stop都是pos) gt_long[, `:=`(start = pos, stop = pos)] setkey(gt_long, chrom, start, stop) # 匹配每个位置所属的窗口,只保留匹配成功的结果 gt_with_window <- foverlaps(gt_long, ranges, type = "within", nomatch = 0L) # 整理需要的列:窗口信息和状态码 gt_with_window <- gt_with_window[, .(chrom = i.chrom, window_start = start, window_end = stop, status_code)]
3. 按窗口统计状态码次数并转宽格式
最后分组统计每个窗口内各状态码的出现次数,再转成你需要的宽格式:
# 按窗口分组,统计每个状态码的出现次数 window_summary <- gt_with_window[, .(count = .N), by = .(chrom, window_start, window_end, status_code)] # 转成宽格式,每个状态码作为一列,缺失的状态码填充0 window_summary_wide <- dcast(window_summary, chrom + window_start + window_end ~ status_code, value.var = "count", fill = 0)
查看结果
你可以用head(window_summary_wide)查看前几个窗口的统计结果,格式就是你想要的:每一行对应一个窗口,列是所有状态码,值为该窗口内的出现次数。
小提示
- 如果只想统计特定的样本列,比如只统计
sample1和sample2,可以在melt时把measure.vars改成c("sample1", "sample2")。 - 如果你的数据包含多个染色体,代码也能正常处理,因为我们全程保留了
chrom列的分组。
备注:内容来源于stack exchange,提问作者zhang
相关产品推荐
相关产品推荐

