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

在分组与时间维度内计算观测值的百分比差异(R语言)

解决方案

要实现同一GroupName和Date分组内,所有观测值两两之间的对称百分比变化计算,可通过生成组内观测值的两两组合再应用公式完成,以下是两种常用实现方式:

方法1:tidyverse 实现(推荐)

借助dplyr和tidyr的语法,代码更直观易维护:

library(tidyverse)

result <- A %>%
  # 按分组维度拆分数据
  group_by(GroupName, Date) %>%
  # 生成组内观测名称的所有两两组合
  expand(ObservationName1 = ObservationName, ObservationName2 = ObservationName) %>%
  # 过滤掉自身对比,以及重复的双向组合(如alpha-beta和beta-alpha只留一个)
  filter(ObservationName1 < ObservationName2) %>%
  # 关联第一个观测的数值
  left_join(A, by = c("GroupName", "Date", "ObservationName1" = "ObservationName")) %>%
  rename(Value1 = Value) %>%
  # 关联第二个观测的数值
  left_join(A, by = c("GroupName", "Date", "ObservationName2" = "ObservationName")) %>%
  rename(Value2 = Value) %>%
  # 计算对称百分比变化
  mutate(Diff = abs(Value1 - Value2) / ((Value1 + Value2) / 2)) %>%
  # 保留目标列并取消分组
  select(GroupName, ObservationName1, ObservationName2, Date, Diff) %>%
  ungroup()

方法2:基础R 实现

无需加载额外包,适合轻量场景:

# 按GroupName和Date拆分数据为多个子数据框
grouped_data <- split(A, list(A$GroupName, A$Date))

# 逐个处理每个分组
result_list <- lapply(grouped_data, function(sub_df) {
  # 获取当前分组的所有观测名称
  obs_names <- unique(sub_df$ObservationName)
  # 生成所有两两组合(无序)
  combos <- combn(obs_names, 2)
  
  # 构建结果行
  combo_df <- data.frame(
    GroupName = rep(unique(sub_df$GroupName), ncol(combos)),
    ObservationName1 = combos[1, ],
    ObservationName2 = combos[2, ],
    Date = rep(unique(sub_df$Date), ncol(combos)),
    stringsAsFactors = FALSE
  )
  
  # 匹配对应的数值并计算差异
  combo_df$Value1 <- sub_df$Value[match(combo_df$ObservationName1, sub_df$ObservationName)]
  combo_df$Value2 <- sub_df$Value[match(combo_df$ObservationName2, sub_df$ObservationName)]
  combo_df$Diff <- abs(combo_df$Value1 - combo_df$Value2) / ((combo_df$Value1 + combo_df$Value2) / 2)
  
  # 保留需要的列
  combo_df[, c("GroupName", "ObservationName1", "ObservationName2", "Date", "Diff")]
})

# 合并所有分组结果为一个数据框
result <- do.call(rbind, result_list)

补充说明

  • 如果需要保留双向组合(同时出现alpha-beta和beta-alpha),只需去掉tidyverse中的filter(ObservationName1 < ObservationName2),或在基础R中用expand.grid(obs_names, obs_names)替代combn并过滤掉ObservationName1 == ObservationName2的行。
  • 公式计算的是对称平均绝对百分比差,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:02:11