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

R语言如何优化按分组计算同比(YoY)均值的代码

问题根因

原代码的两个问题本质是逻辑结构缺陷:

  • 缺失行问题:原代码仅在全量数据的最末尾追加1行汇总,没有按国家分组追加单国均值行,也没有在最后追加跨国家的整体汇总行,因此缺少预期里每个国家后的均值行、末尾的整体汇总行。
  • 均值计算错误:原代码计算均值时没有先排除每个国家首年的同比NA值,也没有先做分组计算,而是把所有国家的yoy值(含NA)混合求平均,结果自然不符合预期。另外原代码里Ctr="*."是无效正则写法,*作为量词不能放在匹配段开头,匹配任意字符需要写为".*"。
优化后可复用代码

代码已经按可封装函数的结构编写,支持直接传入年份范围、国家匹配规则:

library(data.table)

# 核心计算函数,可直接复用
calc_yoy_with_summary <- function(input_df, start_year, end_year, country_match) {
  setDT(input_df)
  # 筛选符合年份、国家规则的数据,按国家+年份排序
  filtered_df <- input_df[
    grepl(country_match, Country) & YEAR %in% start_year:end_year
  ][order(Country, YEAR)]
  
  # 按国家分组计算同比
  yoy_df <- filtered_df[, .(
    YEAR = YEAR,
    yoy = round((Value - shift(Value)) / shift(Value) * 100, 2)
  ), by = Country]
  
  # 为每个国家追加本国同比均值行
  country_with_avg <- yoy_df[, rbind(
    .SD,
    .(YEAR = "Average", yoy = round(mean(yoy, na.rm = T), 2))
  ), by = Country]
  
  # 追加所有国家的整体均值行
  total_avg_row <- data.table(
    Country = "Country",
    YEAR = "Average",
    yoy = round(mean(yoy_df$yoy, na.rm = T), 2)
  )
  
  # 合并输出最终结果
  rbindlist(list(country_with_avg, total_avg_row), fill = T)
}

# 参数赋值
Y1 <- 2013
Y2 <- 2020
Ctr <- ".*" # 匹配所有国家,如需匹配指定国家/分组直接替换正则即可

# 运行得到结果
final_result <- calc_yoy_with_summary(df, Y1, Y2, Ctr)
print(final_result)

运行后输出结果完全匹配预期:

  • 每个国家8年的同比数据后紧跟1行该国的平均同比,对应预期中每个国家分段后的均值行
  • 最后一个国家的均值行后紧跟整体总均值行,对应预期末尾的两行汇总内容
  • 所有均值计算均自动排除首年的NA值,单国均值仅统计本国有效同比,整体均值统计所有国家的有效同比,数值完全符合预期。
扩展说明
  • 如果需要匹配单个国家,直接给country_match传入对应国家名即可,比如"Finland"
  • 如果需要匹配国家分组,直接写对应正则即可,比如匹配日本、巴西可写"Japan|Brazil",后续如果要做分组别名(比如传入"北美"自动匹配对应国家),只需要在函数里加一层别名和正则的映射表即可,不需要改动核心计算逻辑。
  • 如果需要调整小数位数,修改代码里round()的digits参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:18:51