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

基于多条件压缩合并R语言DataFrame中的行

解决R中按玩家组压缩连续胜负streak并计算得分均值的高效方案

核心思路:先给每30行数据标记玩家组ID以隔离跨组streak,再在组内识别连续相同胜负的记录段,最后按组+streak段聚合计算得分均值。以下是两种适配不同场景的高效实现:

方法1:使用data.table(大数据量首选,性能最优)

data.table针对超大数据集做了内存优化,避免冗余复制,处理速度远快于传统tidyverse工具。

# 加载包
library(data.table)

# 构造示例数据(60行=2组玩家,每组30行)
set.seed(123)
df <- data.table(
  win = sample(c(0,1), 60, replace = TRUE),
  sound = sample(1:10, 60, replace = TRUE)
)

# 1. 生成玩家组ID(每30行一组)
df[, group_id := floor((.I - 1)/30) + 1]

# 2. 在每个组内标记连续胜负的streak ID
df[, streak_id := rleid(win), by = group_id]

# 3. 按组+streak聚合,计算得分均值
result_dt <- df[, .(
  win = first(win),  # 同一streak内win值一致,取任意值均可
  sound_mean = mean(sound)
), by = .(group_id, streak_id)]

# 查看结果
head(result_dt)

关键细节

  • .I是data.table内置的行号变量,生成组ID的逻辑高效且无额外计算开销
  • rleid()是专门用于快速识别连续相同值的函数,比手动判断前后值的方法快数倍

方法2:使用dplyr(语法直观,适配tidyverse工作流)

如果习惯tidyverse语法,可采用此方案,数据量不大时性能足够。

# 加载包
library(dplyr)

# 构造示例数据
set.seed(123)
df <- tibble(
  win = sample(c(0,1), 60, replace = TRUE),
  sound = sample(1:10, 60, replace = TRUE)
)

# 1. 生成玩家组ID
df <- df %>%
  mutate(group_id = floor((row_number() - 1)/30) + 1)

# 2. 在每个组内标记streak ID
df <- df %>%
  group_by(group_id) %>%
  mutate(streak_id = cumsum(win != lag(win, default = first(win)))) %>%
  ungroup()

# 3. 聚合计算
result_dplyr <- df %>%
  group_by(group_id, streak_id) %>%
  summarise(
    win = first(win),
    sound_mean = mean(sound),
    .groups = "drop"  # 清除分组状态,避免后续操作干扰
  )

# 查看结果
head(result_dplyr)

关键注意事项

  • 两种方案都严格通过group_id限制streak识别范围,彻底避免跨组误判
  • 若数据集规模达到千万级,优先选择data.table方案,内存占用和处理速度优势明显

内容的提问来源于stack exchange,提问作者grace.cutler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:27:17