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

如何在R Dataframe中按ID分组从累积均值计算单个值?

解决R数据框中从累积均值反推单个测量值的问题

最近我在处理R数据框时碰到个头疼的问题:要从**累积均值(running mean)**反推出每个分组下的单个测量值。手头的原始数据是这样的:

xIDMean
111
125
213
226

这里的Mean列是对应ID分组下,到当前x为止的所有测量值的累积均值。我想要新增一列IndivValues,得到每个行对应的单个测量值,最终目标结果是:

xIDMeanIndivValues
1111
1255
2135
2267

一开始我想着按ID分组用递归函数,但纠结于apply类函数没法直接访问前一条记录,不知道该怎么下手。后来琢磨出了两种简单的实现方法,分享给大家:

方法一:用dplyr分组计算

核心思路是利用累积均值的数学公式反推:假设某个分组里第n行的累积均值是Mean_n,第n-1行的是Mean_{n-1},那么第n行的单个测量值就是:
IndivValues_n = n*Mean_n - (n-1)*Mean_{n-1}

对于每个分组的第一行,n=1,所以单个值就等于它的累积均值,完美符合逻辑。

具体代码如下:

library(dplyr)

# 构造示例数据框
df <- tibble(
  x = c(1, 1, 2, 2),
  ID = c(1, 2, 1, 2),
  Mean = c(1, 5, 3, 6)
)

# 计算单个值
df <- df %>%
  group_by(ID) %>%
  mutate(
    # 标记每个分组内的行号,用来确定是第几个值
    row_num = row_number(),
    # 获取前一行的Mean值,第一行默认用0
    prev_mean = lag(Mean, default = 0),
    # 按公式计算单个测量值
    IndivValues = row_num * Mean - (row_num - 1) * prev_mean
  ) %>%
  # 移除中间辅助列(如果不需要的话)
  select(-row_num, -prev_mean) %>%
  ungroup()

print(df)

运行后就能得到目标结果啦。

方法二:用data.table高效处理(适合大数据)

如果你的数据量很大,data.table的分组操作会更高效,思路和上面完全一致:

library(data.table)

# 构造示例数据表
dt <- data.table(
  x = c(1, 1, 2, 2),
  ID = c(1, 2, 1, 2),
  Mean = c(1, 5, 3, 6)
)

# 计算单个值
dt[, `:=`(
  row_num = .I,
  prev_mean = shift(Mean, fill = 0)
), by = ID]

dt[, IndivValues := row_num * Mean - (row_num - 1) * prev_mean]
# 移除辅助列
dt[, c("row_num", "prev_mean") := NULL]

print(dt)

简单解释下公式的原理:累积均值是前n个值的总和除以n,所以前n个值的总和是n*Mean_n,前n-1个值的总和是(n-1)*Mean_{n-1},两者相减就是第n个单独的测量值。这个逻辑完全覆盖了所有情况,包括分组的第一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:12