在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"))