【问题标题】:Efficient R matrix comparison高效的 R 矩阵比较
【发布时间】:2015-12-14 07:07:22
【问题描述】:

在 R 中,我有两个矩阵 x 和 y,它们都有相同的列数,例如:

x <- matrix(runif(10*20),10,20)
y <- matrix(runif(50*20),50,20)

创建包含以下比较结果的矩阵的最有效方法是什么。比较 x 中的每一行与 y 中的每一行(10x50 行比较),返回 y 行中有多少数小于 x 行中对应的数。将结果放入 10x50 的结果矩阵中。

以下代码有效,但效率不高:

result <- matrix(NA,10,50)    
for (i in 1:10) {
      for (j in 1:50) {
        result[i,j]<- sum(x[i,]>y[j,])
      }
    }

【问题讨论】:

  • 你能把你的example reproducible?.您提供的代码没有运行。
  • 你想说“返回x行中有多少个数小于y行中对应的数”,对吗?
  • 你怎么知道它没有效率?你把它比作什么?
  • runif(50,20) 不是一个东西。
  • @simon wuya,你能澄清/更新你的问题吗?

标签: r performance matrix row


【解决方案1】:

确实你的代码没有运行,但我认为你的意思是y &lt;- matrix(runif(50*20),50,20),对吗?

在这种情况下,您可以使用outer 函数:

outer(rowSums(x), rowSums(y), function(x, y) x > y)

编辑

我明白你的意思了,抱歉,错误也可以得到。我认为这将大大加快您的任务:

result2 <- rowSums(x[rep(1:nrow(x), nrow(y)), ] >
     y[rep(1:nrow(y), each = nrow(x)), ]) %>% 
    matrix(nrow = nrow(x))

【讨论】:

  • 我的意思是,抱歉,问题已被编辑,代码现在可以工作了。你的答案返回布尔值,我的返回一个整数,其出现次数为 x>y
【解决方案2】:

我猜y &lt;- matrix(runif(50)),您可以尝试使用单个循环来加快计算速度:

t(apply(y,1,function(u) rowSums(x<u)))

【讨论】:

    【解决方案3】:

    此答案基于@ColonelBeauvel 的答案。为了加快计算速度,您可以使用一个循环而不是两个循环并在较小的矩阵上循环(在您的示例中为 x)。

    t(apply(x, 1, function(u)colSums(u > t(y))))
    

    另一个重要的注意事项是u &lt; t(y)。 R 按列比较矩阵,这就是为什么首先转置y 很重要。

    带有基准测试的完整示例:

    set.seed(1)
    x <- matrix(runif(10*20),10,20)
    y <- matrix(runif(50*20),50,20)
    
    f0 <- function(x, y) {
    result <- matrix(NA,10,50)
    for (i in 1:10) {
          for (j in 1:50) {
            result[i,j]<- sum(x[i,]>y[j,])
          }
        }
    result
    }
    
    f1 <- function(x, y)t(apply(x,1,function(u)colSums(u>t(y))))
    
    all.equal(f0(x, y), f1(x, y))
    # [1] TRUE
    
    benchmark(f0(x, y), f1(x, y), order="relative")
    #       test replications elapsed relative user.self sys.self user.child sys.child
    # 2 f1(x, y)          100   0.035    1.000     0.032    0.004          0         0
    # 1 f0(x, y)          100   0.253    7.229     0.252    0.000          0         0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多