如何基于相邻行折叠合并大型基础DataFrame?
解决连续相同Occup值的DataFrame行合并问题
嘿,我来帮你搞定这个连续行合并的需求!你需要把DataFrame里连续相邻且Occup值相同的行折叠成区间形式,这个需求在基因组数据处理里挺常见的,我给你两种实用的解决方案:
先确认你的原始数据
首先先把你提供的示例数据再贴一遍,方便后续测试:
dtf = data.frame( chromosome=c("Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1","Chr1"), position=1:17, position2=1:17, name=rep("-",17), Occup=c(rep(0.023,5),rep(0.069,4),rep(0.116,3),rep(0.023,5)) )
方法一:用dplyr包(推荐,代码清晰易读)
dplyr是R中处理数据框的常用工具,步骤很直观:先给连续相同的Occup值分配分组ID,再按分组聚合提取区间起止位置。
# 先安装并加载dplyr(如果没装过的话) # install.packages("dplyr") library(dplyr) # 执行合并操作 dtf_collapsed <- dtf %>% # 先按染色体和name分组(确保不同染色体/name不会被误合并) group_by(chromosome, name) %>% # 创建分组ID:每次Occup和上一行不同时,分组ID加1 mutate(group_id = cumsum(Occup != lag(Occup, default = first(Occup)))) %>% # 按完整分组信息聚合 group_by(chromosome, name, Occup, group_id) %>% summarise( start_position = min(position), # 区间起始位置 end_position = max(position), # 区间结束位置 .groups = "drop" # 取消分组状态 ) %>% select(-group_id) # 移除临时用的分组ID # 查看合并后的结果 print(dtf_collapsed)
运行后得到的结果正是你想要的区间形式:
# A tibble: 4 × 5 chromosome name Occup start_position end_position <chr> <chr> <dbl> <int> <int> 1 Chr1 - 0.023 1 5 2 Chr1 - 0.069 6 9 3 Chr1 - 0.116 10 12 4 Chr1 - 0.023 13 17
方法二:基础R实现(无需额外安装包)
如果你不想加载第三方包,用基础R的aggregate函数也能实现:
# 创建分组ID:diff(Occup) != 0 检测相邻值是否变化,cumsum生成分组 dtf$group_id <- cumsum(c(TRUE, diff(dtf$Occup) != 0)) # 按分组聚合,提取位置的最小和最大值 dtf_collapsed_base <- aggregate( position ~ chromosome + name + Occup + group_id, data = dtf, FUN = function(x) c(min(x), max(x)) ) # 把聚合后的起止位置拆分成单独列,并清理临时列 dtf_collapsed_base <- do.call(data.frame, dtf_collapsed_base) names(dtf_collapsed_base)[5:6] <- c("start_position", "end_position") dtf_collapsed_base <- dtf_collapsed_base[, -4] # 查看结果 print(dtf_collapsed_base)
这个方法得到的结果和上面完全一致,适合不想依赖第三方包的场景。
内容的提问来源于stack exchange,提问作者Rivered
相关产品推荐
相关产品推荐

