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

使用aggregate.data.frame聚合R的data.frame时维度不符问题排查

问题原因与解决办法

哈哈,你这是把aggregate的分组方向搞反啦!我来给你捋清楚问题出在哪,再给你几个靠谱的解决办法~

为什么你的aggregate代码出错?

你用的代码:

aggregate.data.frame(df, by=list(rep(1:3, each=3)), FUN='mean')

这里的by参数传入的rep(1:3, each=3)是一个长度为9的向量,刚好和你的df的行数(9行)一致。aggregate的默认逻辑是:根据by的分组变量对行进行分组,然后对每一列应用聚合函数。所以它会把第1-3行归为一组,4-6行一组,7-9行一组,然后计算每列在每组内的均值,最终得到3行9列的结果——完全和你想要的「每行内按A/B/C列组求均值」的需求反过来了!

正确的实现方法

方法1:Base R 原生实现(无需额外包)

我们可以先把列按前缀(A/B/C)分组,然后对每行计算每个组的均值:

# 提取列名的前缀(A/B/C)作为分组依据
col_groups <- substr(colnames(df), 1, 1)
# 对每行数据,按列分组计算均值,再转置成需要的格式
result <- t(apply(df, 1, function(row) tapply(row, col_groups, mean)))
# 转成data.frame并设置列名
result_df <- as.data.frame(result)
colnames(result_df) <- unique(col_groups)

方法2:用dplyr+tidyr(tidyverse风格,更直观)

如果你熟悉tidyverse工具链,这种方法逻辑更清晰:

library(dplyr)
library(tidyr)

result_df <- df %>%
  # 给每行添加唯一ID,方便后续分组
  mutate(row_id = row_number()) %>%
  # 把宽格式数据转成长格式
  pivot_longer(-row_id, names_to = "col_name", values_to = "value") %>%
  # 从列名中提取A/B/C分组
  mutate(group = substr(col_name, 1, 1)) %>%
  # 按行ID和分组计算均值
  group_by(row_id, group) %>%
  summarise(mean_val = mean(value), .groups = "drop") %>%
  # 转回宽格式
  pivot_wider(names_from = group, values_from = mean_val) %>%
  # 移除行ID列
  select(-row_id)

方法3:用data.table(大数据量下更高效)

如果你的数据量很大,data.table的方法速度会更快:

library(data.table)

# 把df转成data.table格式
setDT(df)[, row_id := .I]
# 转长格式、分组计算均值、再转回宽格式
result_df <- melt(df, id.vars = "row_id")[, 
  .(mean_val = mean(value)), 
  by = .(row_id, group = substr(variable, 1, 1))
][, dcast(.SD, row_id ~ group, value.var = "mean_val")][, row_id := NULL]

以上三种方法都能得到你想要的9行3列结果,每行对应原df的一行,列分别是A_、B_、C_*列的均值。

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

相关产品推荐
方舟 Agent Plan

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

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