You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中编写循环按连续相同abs.sum值合并数据框行?

合并连续相同abs.sum值的数据框行(按chr分组)

需求说明

针对每个chr分组,将连续具有相同abs.sum值的行合并,保留该组最小的start值和最大的end值。

测试数据

r1 <- c(1, 1,1000,2)
r2 <- c(1, 1001,2000, 2)
r3 <- c(1, 2001,3000, 2)
r4 <- c(1, 3001,4000, 1)
r5 <- c(1, 4001,5000, 3)
r6 <- c(1, 5001,6000, 3)
r7 <- c(2, 1,1000,2 )
r8 <- c(2, 1001,2000, 1)
r9 <- c(2, 2001,3000, 2)
r10 <- c(2, 3001,4000, 1)
r11 <- c(2, 4001,5000, 1)
test <- rbind(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)
test <- as.data.frame(test)
colnames(test) <- c("chr", "start","end", "abs.sum")
rownames(test) <- NULL

原始数据框结构:

chr start  end abs.sum
1    1     1 1000       2
2    1  1001 2000       2
3    1  2001 3000       2
4    1  3001 4000       1
5    1  4001 5000       3
6    1  5001 6000       3
7    2     1 1000       2
8    2  1001 2000       1
9    2  2001 3000       2
10   2  3001 4000       1
11   2  4001 5000       1

期望结果:

chr start  end abs.sum
1   1     1 3000       2
2   1  3001 4000       1
3   1  4001 6000       3
4   2     1 1000       2
5   2  1001 2000       1
6   2  2001 3000       2
7   2  3001 5000       1

错误尝试及问题

尝试编写的for循环:

for (i in 1:nrow(test)) {
        
        if (test$abs.sum[i] == test$abs.sum[i + 1]) {
                test$end[i] <- test$end[i+1]
                test <- test[-i + 1]
                test <- test[-(i + 1),]
        }
        
}

运行后报错:

Error in if (test$abs.sum[i] == test$abs.sum[i + 1]) { :
argument is of length zero

错误原因:循环中直接修改了数据框的行数,导致后续迭代时i+1超出数据框的行范围;同时删除行的逻辑错误(test[-i + 1]语法错误,且连续删除行会打乱索引)。


解决方法

方法一:使用dplyr包(推荐)

无需手动写循环,用dplyr的分组和聚合功能即可快速实现,核心是给连续相同的abs.sum值组生成分组标识:

library(dplyr)

test_result <- test %>%
  group_by(chr) %>%
  # 生成连续相同abs.sum的分组标识
  mutate(grp = cumsum(abs.sum != lag(abs.sum, default = abs.sum[1]))) %>%
  group_by(chr, grp, abs.sum) %>%
  # 聚合取最小start、最大end
  summarize(start = min(start),
            end = max(end),
            .groups = "drop") %>%
  select(chr, start, end, abs.sum) # 调整列顺序

print(test_result)

运行后即可得到期望结果。

方法二:手动编写循环实现

如果一定要用循环,建议从后往前遍历(避免删除行后索引混乱),同时按chr分组处理:

# 复制原始数据避免修改原数据
test_loop <- test
i <- nrow(test_loop)

while (i > 1) {
  # 仅当当前行和上一行chr相同、abs.sum相同时合并
  if (test_loop$chr[i] == test_loop$chr[i-1] && test_loop$abs.sum[i] == test_loop$abs.sum[i-1]) {
    # 更新上一行的end为当前行的end
    test_loop$end[i-1] <- test_loop$end[i]
    # 删除当前行
    test_loop <- test_loop[-i, ]
  }
  i <- i - 1
}

print(test_loop)

这种写法从最后一行开始往前检查,避免了删除行后后续索引失效的问题,同样能得到正确结果。


内容的提问来源于stack exchange,提问作者Louise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:37:01