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

求助:在R语言中计算对战双方历史胜场次数(附数据集)

我来帮你解决这个历史对战统计的问题!针对你15000行的数据集,我准备了两种高效的R实现方案,既能保证准确性,也能应对较大的数据量:

首先确认你的示例数据

day <- c(1,2,3,4,5,6,7,8) 
id1 <- c(100,200,100,400,200,200,300,200) 
id2 <- c(200,400,200,300,400,100,400,100) 
result<-c(1,0,1,0,1,0,0,1) 
tables <- data.frame(day,id1,id2,result)

方案1:使用dplyr(推荐,代码更清晰易维护)

dplyr的分组和窗口函数能让我们很直观地处理逐行历史统计:

library(dplyr)

tables_processed <- tables %>%
  # 先按day排序,确保按时间顺序统计历史
  arrange(day) %>%
  # 生成标准化对战组合:把每对id按从小到大排序后拼接,保证同一对战组统一归类
  mutate(pair = paste(pmin(id1, id2), pmax(id1, id2), sep = "-")) %>%
  # 按标准化对战组合分组
  group_by(pair) %>%
  mutate(
    # 标记当前行的id1是标准化组合中的第一个还是第二个元素
    id1_is_first = id1 == pmin(id1, id2),
    # 转换结果:对标准化组合来说,first_win=1表示第一个id赢,0表示第二个id赢
    first_win = ifelse(id1_is_first, result, 1 - result),
    # 计算HTH1:当前行之前,id1战胜id2的次数
    HTH1 = ifelse(
      id1_is_first,
      lag(cumsum(first_win), default = 0),  # id1是第一个元素,取之前first_win的累计
      lag(cumsum(1 - first_win), default = 0)  # id1是第二个元素,取之前second_win的累计
    ),
    # 计算HTH2:当前行之前,id2战胜id1的次数,逻辑与HTH1相反
    HTH2 = ifelse(
      id1_is_first,
      lag(cumsum(1 - first_win), default = 0),
      lag(cumsum(first_win), default = 0)
    )
  ) %>%
  ungroup() %>%
  # 移除临时辅助列
  select(-pair, -id1_is_first, -first_win)

# 查看结果
print(tables_processed)

方案2:Base R实现(无需加载额外包)

如果你不想依赖dplyr,用Base R也能实现同样的逻辑:

# 先按day排序数据,保证时间顺序正确
tables <- tables[order(tables$day), ]

# 创建标准化对战组合列
tables$pair <- apply(tables[, c("id1", "id2")], 1, function(x) paste(sort(x), collapse = "-"))

# 标记当前id1是否是标准化组合中的第一个元素
tables$id1_is_first <- mapply(function(a, b) a == min(a, b), tables$id1, tables$id2)

# 转换结果为标准化组合的胜负标记
tables$first_win <- ifelse(tables$id1_is_first, tables$result, 1 - tables$result)

# 按对战组合分组计算累计胜负次数
tables$cum_first_win <- ave(tables$first_win, tables$pair, FUN = cumsum)
tables$cum_second_win <- ave(1 - tables$first_win, tables$pair, FUN = cumsum)

# 计算HTH1和HTH2:取当前行之前的累计值(用c(0, head(...))实现lag效果)
tables$HTH1 <- ifelse(
  tables$id1_is_first,
  c(0, head(tables$cum_first_win, -1)),
  c(0, head(tables$cum_second_win, -1))
)
tables$HTH2 <- ifelse(
  tables$id1_is_first,
  c(0, head(tables$cum_second_win, -1)),
  c(0, head(tables$cum_first_win, -1))
)

# 移除临时辅助列
tables <- tables[, !names(tables) %in% c("pair", "id1_is_first", "first_win", "cum_first_win", "cum_second_win")]

# 查看结果
print(tables)

关键逻辑解释

两种方案的核心思路是一致的:

  1. 标准化对战组合:把每一对对战的id按固定顺序(比如从小到大)拼接,这样不管id1和id2的顺序如何,同一组对战都会被归为同一个分组,避免重复统计。
  2. 映射历史胜负:根据当前行id1在标准化组合中的位置,把历史胜负结果映射到id1和id2的关系上,确保统计的是当前行之前的对战次数(用lag或head排除当前行的结果)。

运行任意一种方案后,你都会得到和期望完全一致的HTH1和HTH2列,而且针对15000行的数据,两种方案的效率都足够应对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:27