在R中进行两个嵌套for循环的快速方法

在R中进行两个嵌套for循环的快速方法,r,for-loop,optimization,R,For Loop,Optimization,我需要求两个向量的任意两个元素之间的差。 如果A使用purrr::map2: library(tidyverse) N = 300 A = runif(N) B = runif(N) R = c() print( system.time( result <- map( .x = A, .f = ~ c(.x - B)) %>% unlist ) ) 如果我现在引起您的注意,请查看purr的详细介绍。您可以使用expand.grid对方法进

我需要求两个向量的任意两个元素之间的差。
如果
A使用
purrr::map2

library(tidyverse)

N = 300
A = runif(N)
B = runif(N)
R = c()

print(
  system.time(
    result <- map(
      .x = A,
      .f = ~ c(.x - B)) %>% unlist
  )
)

如果我现在引起您的注意,请查看
purr

的详细介绍。您可以使用
expand.grid
对方法进行矢量化:

A <- runif(300)
B <- runif(300)

library(dplyr)
R <- as.data.frame(expand.grid(A,B)) %>%
       mutate(Var3 = Var2-Var1)  
这需要:

user  system elapsed 
0.02    0.00    0.02
你的职能是:

 user  system elapsed 
42.39    0.43   42.90    

最快的基本解决方案是使用
外部

as.vector(outer(B,A,"-"))
令我惊讶的是,
map2_dbl
实际上比
outer
快了很多:

as.vector(outer(B,A,"-"))
毫不奇怪,
map2_dbl
似乎更快,但这是因为它没有计算A和B中的每个值组合:

      test elapsed relative
3 CP(A, B)    7.54   47.125 # using expand.grid
2 JL(A, B)    0.16    1.000 # using map2_dbl
1 JM(A, B)    3.13   19.563 # using outer
但是:



其他选项包括
apply
函数系列,但我喜欢
purr::map
,因为我认为这更直观一点,因为这是关于速度的,其他答案也提供了这一点,您介意添加一点关于运行此代码与OP相比实际花费的时间吗?显然这更快。它没有计算所有的组合,所以它没有按照OP的要求去做。试试
哈哈,你说得对@Joris Meys,很抱歉@詹劳日嗯。。。现在看来,你似乎在答案中复制粘贴了Chi-Pak的代码。老实说,我不认为
map
是一个明智的解决方案。这是一个很好的函数,但用途完全不同。
purrr::map2_dbl
更快。这对300个值来说并不重要,但我假设OP希望将其放大。嗯……好的。首先,您应该表明您测试了性能上的差异(也将其与我的方法进行比较)。第二,我知道
purrr:map
更快,因为我实际测试了我的方法。第三,我给了你目前仅有的一票。第四,我们同时发布,这就是为什么我的帖子存在的原因。第五,互联网积分是不真实的,你不能用它们买任何东西。我的评论似乎让你不安。那不是我的本意,抱歉。我喜欢认为我只是对找到问题的最佳解决办法感兴趣。我应该说得更清楚。下次再修改你原来的答案就行了。遵循@Joris Meys的示例
外部(A、B、
-
?看,报价越来越乱。nice@zx8754,想不到baseR的解决方案会这么快@zx8754太晚了,我敲了敲:-)这是一个完全相同的问题,减法等等。@zx8754谢谢你的重复。我永远也找不到它!感谢谷歌。但仍然是一个很好的问题和努力。我刚才尝试了
N=100000
,此时
outer
占用了我机器上太多的内存(
错误:无法分配大小为74.5 Gb的向量
map2_dbl
仍然可以正常工作,只需0.14秒。@zx8754如果您有代码,如果您对此感兴趣,可以使用自己的CPU。我还弄明白了为什么
map2\u dbl
这么快:因为它不是问题的解决方案:-)啊,为什么
map2\u dbl
更快是有道理的。很高兴知道
outer
解决方案。@JorisMeys+1感谢您的建议
 user  system elapsed 
42.39    0.43   42.90    
as.vector(outer(B,A,"-"))
      test elapsed relative
3 CP(A, B)    7.54   47.125 # using expand.grid
2 JL(A, B)    0.16    1.000 # using map2_dbl
1 JM(A, B)    3.13   19.563 # using outer
> A <- 1:3
> B <- 3:1
> JL(A,B)
[1] -2  0  2
> JM(A,B)
[1]  2  1  0  1  0 -1  0 -1 -2
library(tidyverse)

JM <- function(A,B){
  as.vector(outer(B,A,"-"))
}

JL <- function(A,B){
  map2_dbl(.x = A, 
           .y = B, 
           .f = ~ c(.x - .y))
}

CP <- function(A,B){
  as.data.frame(expand.grid(A,B)) %>%
    mutate(Var3 = Var2-Var1)
}

library(rbenchmark)

A <- runif(1000)
B <- runif(1000)

benchmark(JM(A,B),
          JL(A,B),
          CP(A,B),
          replications = 100,
          columns = c("test","elapsed","relative"))