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

寻找比ddply按分组聚合变量更高效的实现方案

解决方案

原代码性能极差的核心原因是ddply属于plyr包的旧版分组函数,处理大数据时会产生大量临时数据副本,内存开销极高。你已经将数据转为data.table对象,直接使用data.table原生的分组赋值语法即可实现相同逻辑,全程原地操作无额外拷贝,性能提升至少百倍。

最优实现(data.table版本)

# 不需要修改原数据可先复制,不需要保留原数据可直接操作t对象
t2 <- copy(t)

# 生成aj1.consecutive字段,.N对应原逻辑的n(),代表分组内行数
t2[, aj1.consecutive := (sum(j2.consecutive) - j2.consecutive)/(.N - 1), by = .(oid, aid)]

# 生成apj1.consecutive字段
t2[, apj1.consecutive := (sum(j2.consecutive) - j2.consecutive)/(.N - 1), by = .(oid, pid)]

# 按要求排序
setorder(t2, aid, o4.in)

如果存在分组内只有1条记录的场景,计算时会出现除零得到NaN的情况,可根据业务需要加判断逻辑替换默认值,示例:

t2[, aj1.consecutive := fifelse(.N == 1, 0, (sum(j2.consecutive) - j2.consecutive)/(.N - 1)), by = .(oid, aid)]

该方案处理400万条数据仅需几秒,不会出现内存不足导致Rstudio崩溃的问题,运行结果和原有ddply实现完全一致。

备选实现(dplyr版本)

如果更习惯tidyverse语法,用dplyr的原生分组语法也远快于ddply:

library(dplyr)
t2 <- t %>%
  group_by(oid, aid) %>%
  mutate(aj1.consecutive = (sum(j2.consecutive) - j2.consecutive)/(n()-1)) %>%
  ungroup() %>%
  group_by(oid, pid) %>%
  mutate(apj1.consecutive = (sum(j2.consecutive) - j2.consecutive)/(n()-1)) %>%
  ungroup() %>%
  arrange(aid, o4.in)

内容的提问来源于stack exchange,提问作者J.K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 11:36:04