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

R语言中修正ifelse循环代码生成目标矩阵G的方法

修正R代码以生成目标比较次数矩阵

我来帮你解决这个问题!你的代码主要有两个核心问题导致结果不符合预期,我们一步步拆解并修正:

原代码的问题分析

  1. 不必要的行遍历:你用了apply(dt, 1, ...)按行遍历整个数据框,但函数内部完全没用到每行的y参数,这导致同一组比较被重复计算了12次(数据框总行数),结果被无意义地放大。
  2. 错误的比较逻辑:dt$V2[dt$V1==m] < dt$V2[dt$V1==n]是按位置逐元素比较两个组的V2向量,而不是执行所有元素的两两交叉比较——这和你需要的“统计前者所有元素小于后者所有元素的总次数”需求完全不符。

修正后的代码

首先先确认我们的输入数据:

# 构建输入数据框
dt <- data.frame(
  V1 = rep(1:3, each = 4),
  V2 = c(60, 30, 38, 46, 29, 35, 13, 82, 100, 72, 63, 45)
)

方法1:修正原有循环

我们先按V1分组提取V2值,避免重复计算,然后在循环中执行正确的两两交叉比较:

l1 <- 1:3
G <- matrix(data = 0, nrow = 3, ncol = 3)

# 按V1分组提取V2值,存储为列表
groups <- split(dt$V2, dt$V1)

for (m in l1) {
  for (n in l1) {
    if (m == n) {
      G[m, n] <- 0  # 同一组元素自己和自己比较,不会有小于的情况
      next
    }
    # 计算m组所有V2值小于n组所有V2值的总次数
    G[m, n] <- sum(outer(groups[[as.character(m)]], groups[[as.character(n)]], "<"))
  }
}

# 打印结果
print(G)

方法2:更简洁的向量化实现

利用outer函数直接对分组后的列表进行操作,无需手动循环:

groups <- split(dt$V2, dt$V1)
G <- outer(groups, groups, function(x, y) sum(x < y))

# 打印结果
print(G)

两种方法运行后都会得到你期望的结果:

[,1] [,2] [,3]
[1,]    0    5   14
[2,]    5    0   13
[3,]   14   13    0

逻辑验证(以G[1,2]为例)

V1=1的V2值为[60, 30, 38, 46],V1=2的V2值为[29, 35, 13, 82],两两交叉比较后统计前者小于后者的次数:

  • 60仅小于82 → 1次
  • 30小于35、82 → 2次
  • 38仅小于82 →1次
    -46仅小于82 →1次
    总计1+2+1+1=5次,和目标矩阵中的G[1,2]完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:13:18