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

在R中为每个ID计算年度均值:按行求每12列均值的方法

解决每个ID的年度均值计算问题

你的原代码通过colMeans对每年第1个月的列求均值,得到的是所有ID在该年度首月的整体均值,而非每个ID的全年均值。要实现每个ID对应每年的均值计算,核心是先把宽格式的月度数据转为长格式,再按ID和年份分组统计。以下是几种可行的实现方法:

Base R 实现

适合不想加载额外包的场景:

# 将宽格式转为长格式,假设第一列是ID列(列名为"ID")
long_df <- reshape(df, 
                   direction = "long",
                   varying = names(df)[-1],  # 指定所有月度数据列
                   v.names = "value",        # 月度值的列名
                   timevar = "date",         # 日期列的列名
                   times = names(df)[-1])    # 用原月度列名作为日期值

# 从日期列提取年份(假设列名格式为XYYYY.MM.DD,先去掉开头的X,再按.分割取第一部分)
long_df$year <- sub("^X", "", long_df$date) %>% 
  strsplit("\\.") %>% 
  sapply(function(x) x[1])

# 按ID和年份分组计算年度均值,保留1位小数
annual_means <- aggregate(value ~ ID + year, data = long_df, 
                          FUN = function(x) round(mean(x, na.rm = TRUE), 1))

dplyr + tidyr 实现

代码更直观易读,适合日常数据分析:

library(dplyr)
library(tidyr)

annual_means <- df %>%
  # 把所有月度列转为长格式:ID保留,其他列转为日期-值对
  pivot_longer(cols = -ID, names_to = "date", values_to = "value") %>%
  # 从日期列提取年份(适配XYYYY.MM.DD格式)
  mutate(year = sub("^X", "", date) %>% str_split("\\.", simplify = TRUE)[,1]) %>%
  # 按ID和年份分组
  group_by(ID, year) %>%
  # 计算年度均值并保留1位小数,最后取消分组
  summarise(annual_mean = round(mean(value, na.rm = TRUE), 1), .groups = "drop")

data.table 实现

处理大数据集时效率更高:

library(data.table)

# 转换为data.table格式
setDT(df)
annual_means <- melt(df, id.vars = "ID", variable.name = "date", value.name = "value")[,
  # 提取年份
  year := sub("^X", "", date) %>% tstrsplit("\\.")[[1]]
][, 
  # 按ID和年份分组计算均值
  .(annual_mean = round(mean(value, na.rm = TRUE), 1)), 
  by = .(ID, year)
]

注意事项

如果你的月度列名格式不是XYYYY.MM.DD(比如是2000_01或200001),需要调整提取年份的代码:

  • 若列名是2000_01:用year = sub("_.*", "", date)提取年份
  • 若列名是200001:用year = substr(date, 1, 4)提取年份

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:34:50